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..
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.
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.
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With