Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LSSerializer is missing xmlns attribute when serializing an xml document in jdk 11 (works fine in jdk 8)

Tags:

java

xml

java-11

I am using LSSerializer `linked below' for serializing xml documents in my application and now that I am moving from java 8 to 11, I have seen that the serialized xml documents are missing the default xml namespace attribute ("xmlns"). It seems the LSSerializer implementation used in jdk 8 has been replaced jdk 9 onwards. And the new implementation misses the xmlns attribute when serialising a DOM Document (a bug?)

To illustrate the issue, the following code when compiled and run in java 11 misses the xmlns attribute in xml (it works fine with java 8)

import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.*;


public class Test {
    public static void main(String[] args) {
        String xml = "<bio><body xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\"><p>test</p></body></bio>";
        try {
            InputStream inputStream = new ByteArrayInputStream(xml.getBytes("UTF-8"));

            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document doc = builder.parse(inputStream);
            Element node = doc.getDocumentElement();

            DOMImplementationLS domImplementation = (DOMImplementationLS)doc.getImplementation();
            LSSerializer lsSerializer = domImplementation.createLSSerializer();
            String output = lsSerializer.writeToString(node);
            System.out.println(output);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output in java8:

<?xml version="1.0" encoding="UTF-16"?>
<bio><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"><p>test</p></body></bio>

Output in java11:

<?xml version="1.0" encoding="UTF-16"?><bio><body xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"><p>test</p></body></bio>

I have checked this by altering different DOM Configuration properties link below of the LSSerializer object like "namespace-declarations", "discard-default-content",etc but it is missing xmlns attribute in all cases.

LSSerialize

altering different DOM Configuration properties

like image 987
pc__ Avatar asked Feb 25 '19 07:02

pc__


1 Answers

I encountered the same problem. I fixed it by setting the namespaceAware to true, which is default false.

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
like image 62
Chuk Avatar answered Sep 21 '22 23:09

Chuk