Since moving to java 1.7 Xml Document Element does not indent

那年仲夏 提交于 2019-12-19 02:52:10

问题


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..


回答1:


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.




回答2:


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.




回答3:


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
    }



回答4:


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.



来源:https://stackoverflow.com/questions/18249490/since-moving-to-java-1-7-xml-document-element-does-not-indent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!