On 10/28/11 3:44 PM, Eric Johnson wrote:
> Hi Sean,
> 
> Thanks for the feedback.
> 
> I ended solving this by wrapping all the declared namespaces in an 
> instance of a class that extends XMLStructure (actually, the default one 
> - this would have been javax.xml.crypto.dom.DOMStructure but for the 
> fact that with the GenXDM port we need a GenXDMStructure equivalent of 
> that.). I then add that object to the "content" of the XMLObject. Then, 
> when marshaling the object, I check to see if the referenced node is a 
> namespace declaration, and declare the namespace in the target output 
> (rather than inserting the source node).
> 
> This isn't quite a perfect solution, because if the caller modifies the 
> namespace declaration, then that update will be reflected in the later 
> marshaling, but it works. And it isn't any different in that regard from 
> the solution in 1.4.6, except it is no longer destructive to the source 
> document used when unmarshaling.
> 
> Here's a question - with the current implementation in 1.4.6, it strikes 
> me that attributes like xml:base, xml:id, and xml:lang would also be 
> preserved in the new marshaling - I'm not sure that's correct. Or is it? 
> Certainly, my change to preserve namespaces doesn't preserve those 
> attributes, but perhaps it should?

Yes, if you are using C14N 1.1 : http://www.w3.org/TR/xml-c14n11/

--Sean


> 
> -Eric.
> 
> On 10/26/11 5:40 PM, Sean Mullan wrote:
>> On 10/26/11 8:30 AM, Eric Johnson wrote:
>>> 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 ?
>> Yes.
>>
>>> 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?
>> The underlying problem is that you cannot access the namespace declarations 
>> via
>> JSR 105 XMLObject API. That should be fixed eventually but since there are no
>> immediate plans for reving the API, we need to work around it.
>>
>> Your first solution seems better. The second solution is not compliant with 
>> the
>> XMLObject.getContent() API.
>>
>> --Sean
>>
>>

Reply via email to