In the 1.4.6 release of Santuario Java, the DOMXMLObject class underwent
a small set of changes.
Specifically, it appears that the class now holds on to the objElem
passed to the constructor:
public DOMXMLObject(Element objElem, XMLCryptoContext context, Provider
provider);
It appears to do this so that the objElem can be re-used upon calling
the "marshal" method.
Is this related to https://issues.apache.org/jira/browse/SANTUARIO-283 ?
I've been changing the marshaling code in the GenXDM port so that it
makes minimal assumptions about the implementation of the various
javax.xml.crypto APIs.
That is, in the GenXDM port, the equivalent marshal function looks like:
public static<N> void marshal(XMLObject xmlObj, MutableModel<N> model, N
parent, String dsPrefix, XMLCryptoContext context)
throws MarshalException {
NodeFactory<N> factory = model.getFactory(parent);
N objElem = factory.createElement
(XMLSignature.XMLNS, "Object", dsPrefix);
// set attributes
DOMUtils.setAttributeID(factory, model, objElem, "Id", xmlObj.getId());
DOMUtils.setAttribute(factory, model, objElem, "MimeType",
xmlObj.getMimeType());
DOMUtils.setAttribute(factory, model, objElem, "Encoding",
xmlObj.getEncoding() );
// create and append any elements and mixed content, if necessary
@SuppressWarnings("unchecked")
List<XMLStructure> content = xmlObj.getContent();
for (XMLStructure object : content) {
Marshaller.marshal(object, model, objElem, dsPrefix, context);
}
model.appendChild(parent, objElem);
}
Note that this method is both static, and takes a generic XMLObject as a
parameter, rather than the Apache implementation specific version of
DOMXMLObject.
I'm inclined to change my port so that upon unmarshalling the node, it
captures the namespace declarations on the node, and then in the marshal
code above, I add a check to see if the xmlObj is an instance of a
DOMXMLObject, and only then see if the specific known implementation has
unmarshalled any namespace declarations, and if it has, add those as
part of what gets output.
Alternately, I could add the namespace declarations as members of the
getContent() collection, and if I detect them, write out the namespace
declarations.
Either of the above has the upside that you can then "marshal" the
object as many times as you want, to as many target trees you want,
without worrying that the same element will be used over and over again.
Comments?
-Eric.