Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java XML Transformer Node to String remove namespace

Tags:

java

xml

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.

like image 891
Evgeni Dimitrov Avatar asked Oct 17 '25 04:10

Evgeni Dimitrov


1 Answers

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"/>).

like image 154
Michael Kay Avatar answered Oct 19 '25 20:10

Michael Kay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!