Since moving to java 1.7 Xml Document Element does

2019-02-14 16:43发布

I'm trying to indent XML which generated by Transformer. All the DOM Node are being Indent as expected except for the First Node - The Document Element. document element does not start in a new line , just concat right after the XML Declaration.

This bug arise when I moved to java 1.7 , when using java 1.6 or 1.5 it does not happen.

My code :

ByteArrayOutputStream s = new OutputStreamWriter(out, "utf-8");

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4");

transformer.transform(new DOMSource(doc), new StreamResult(s));

The output:

<?xml version="1.0" encoding="UTF-8"?><a>
       <b>bbbbb</b>
 </a>

Anyone knows why ?

btw, when I add the property

transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");

It work as expected , but the xml declaration is changed, it now have the standalone property as well, and i don't want to change the xml declaration..

4条回答
可以哭但决不认输i
2楼-- · 2019-02-14 17:09

Ok ,

I found in Java API this :

If the doctype-system property is specified, the xml output method should output a document type declaration immediately before the first element.

SO I used this property

 transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");

and it solve my problem with out changed my xml declartion.

Thanks.

查看更多
欢心
3楼-- · 2019-02-14 17:19

Xalan has at some point changed the behavior regarding the newline character after the XML declaration.

OpenJDK (and thus Oracle JDK, too) has implemented a workaround for this problem. This workaround can be enabled by setting a special property on the Transformer object:

try {
    transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes");
} catch (IllegalArgumentException e) {
    // Might be thrown by JDK versions not implementing the workaround.
} 

This way, the old behavior (printing a newline character after the XML declaration) is restored without adding the standalone attribute to the XML declaration.

查看更多
forever°为你锁心
4楼-- · 2019-02-14 17:26

This seems to be a problem (bug) of the XML implementaion in Java. The only way to get a linebreak after the XML declaration is to explicitly specify the standalone attribute. You may set it to no, which is the implicit default, even if it is completely irrelevant when not using a DTD.

查看更多
不美不萌又怎样
5楼-- · 2019-02-14 17:29

For me writing the XML declaration to the Writer or OutputStream before writing the XML and telling the transformer to omit declaration was the only thing that worked. The only other solution to preserve the spacing appears to be VTD-XML library.

    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"").append(doc.getXmlVersion()).append("\"");
    sb.append(" encoding=\"").append(doc.getXmlEncoding()).append("\"");
    if (doc.getXmlStandalone()) {
        sb.append(" standalone=\"").append("" + doc.getXmlStandalone()).append("\"");
    }
    sb.append("?>").append("\n");

    writer.write(sb.toString());
            TransformerFactory tf = TransformerFactory.newInstance();
    try {
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    }
    catch (Exception e)  {
    //snipped out for brevity
    }
查看更多
登录 后发表回答