Reputation: 137
Considering the following XML
<TestFile>
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
</TestFile>
In the past I have parsed using Java DOM to set the default namespace like this
MyDoc.getDocumentElement().setAttribute("xmlns", this.NameSpaceAsString);
In earlier versions of Java 8, this produced a proper XML like this
<TestFile xmlns="mynamespace.com">
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
However, with an upgrade to Java 11, Im now getting 2 default namespaces on the top 2 nodes with one of them being empty like this
<TestFile xmlns="mynamespace.com">
<TestHeader xmlns=" ">
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
Im not sure what changed that would cause getDocumentElement to find 2 nodes or setAttribute to set in 2 places.
Upvotes: -1
Views: 75
Reputation: 12817
Given this code:
public static void main(String[] args) throws Exception {
System.out.println("JVM version: " + System.getProperty("java.version"));
Document d = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new File("data.xml"));
d.getDocumentElement().setAttribute("xmlns", "xyzzy");
TransformerFactory
.newInstance()
.newTransformer()
.transform(new DOMSource(d), new StreamResult(System.out));
}
The output for four different java versions is:
JVM version: 1.7.0_352
<?xml version="1.0" encoding="UTF-8" standalone="no"?><TestFile xmlns="xyzzy">
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
</TestFile
JVM version: 1.8.0_282b08-internal
<?xml version="1.0" encoding="UTF-8" standalone="no"?><TestFile xmlns="xyzzy">
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
</TestFile>
JVM version: 11.0.25
<?xml version="1.0" encoding="UTF-8" standalone="no"?><TestFile xmlns="xyzzy">
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
</TestFile>
JVM version: 23.0.1
<?xml version="1.0" encoding="UTF-8" standalone="no"?><TestFile xmlns="xyzzy">
<TestHeader>
<FileVersion>2.00</FileVersion>
<FileCountry>GB</FileCountry>
<FileRegion>LND</FileRegion>
</TestHeader>
</TestFile>
Note that it is always a bad idea managing namespaces with a namespace unaware XML processor.
Update:
The "correct" way to change the namespace of every Element in the document would be something like this:
DocumentBuilderFactory f = DocumentBuilderFactory.newDefaultInstance();
f.setNamespaceAware(true);
Document d = f
.newDocumentBuilder()
.parse(new File("data.xml"));
TreeWalker tw = ((DocumentTraversal)d).createTreeWalker(d, NodeFilter.SHOW_ELEMENT, null, false);
Node node;
while((node = tw.nextNode()) != null) {
if (node instanceof Element e) {
d.renameNode(e, "xyzzy", e.getTagName());
}
}
TransformerFactory
.newInstance()
.newTransformer()
.transform(new DOMSource(d), new StreamResult(System.out));
This does not involve "cheating" by adding an "xmlns" attribute to an otherwise namespace unaware document
Upvotes: 2