Java XML Transformer Node to String remove namespace

Evgeni Dimitrov :

I use the following method to transform an xml node to String (commonly found on the web):

String nodeToString(Node node) {
   StringWriter sw = new StringWriter();
   try {
      Transformer t = TransformerFactory.newInstance().newTransformer();
      t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
      t.setOutputProperty(OutputKeys.INDENT, "yes");
      t.transform(new DOMSource(node), new StreamResult(sw));
   } catch (TransformerException te) {
     throw ...
   }
   return sw.toString();
}

The Nodes transformed to String are not whole xml documents but just parts of a bigger XML. The problem is that after transformed to String the root element of the Node has an xmlns added to it, which causes problems.

This is the String returned by nodeToString :

<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <header>
         ...
     </header>
     <payload>
         ...
     </payload>
</doc> 

Worst part is that this does not happen on my machine and the Test environment but only on the UAT and I struggle to find the difference between the environments.

Does anybody bumped into this problem and know what causes it?

Edit:

The original document looks like this:

<docs>
    <doc> 
         <header>
             ...
         </header>
         <payload>
             ...
         </payload>
    </doc>  
    <doc> 
         <header>
             ...
         </header>
         <payload>
             ...
         </payload>
    </doc>   
    // more <doc>s
<docs>  

It's splitted with XPath to Nodes (each Node is one element) then some business logic is applied (some nodes are removed, some are grouped differently) and at the end I have to turn it back to String.

Michael Kay :

Assuming that the xsi namespace is actually declared on some ancestor element, this is the correct behaviour, even though it might be problematic for you. In the XDM data model used by XSLT (and also by the JAXP identity transformer), an element has an in-scope namespace declaration for every namespace declared on that element or any of its ancestors, and when the element is serialized, all non-redundant in-scope namespace declarations are output.

The reason for this is that some element or attribute might actually use the declared namespace prefix (this is common in XSLT and XSD but rare in other XML vocabularies).

You can get rid of the unwanted namespaces by doing a transformation before serializing (with XSLT 2.0+ that's as simple as doing <xsl:copy-of copy-namespaces="no"/>).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=358526&siteId=1