Puce Puce - 13 days ago 5
Java Question

XMLStreamWriter: indentation

is there really no way to directly write formatted XML using javax.xml.stream.XMLStreamWriter (Java SE 6)??? This is really unbelievable, as other XML APIs such as JAXB and some DOM libraries are able to do this. Even the .NET XMLStreamWriter equivalent is able to this AFAIK (if I remember correctly the class is System.Xml.XmlTextWriter).

This means the only option I have is to reparse the XML to generate formatted output??

E.g.:

StringWriter sw = new StringWriter();
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(sw);
writeXml(xmlStreamWriter);
xmlStreamWriter.flush();
xmlStreamWriter.close();

TransformerFactory factory = TransformerFactory.newInstance();

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

StringWriter formattedStringWriter = new StringWriter();
transformer.transform(new StreamSource(new StringReader(sw.toString())), new StreamResult(formattedStringWriter));
System.out.println(formattedStringWriter);


The problem with this solution is the property "{http://xml.apache.org/xslt}indent-amount". I didn't find any documentation about it and it doesn't seem to be guaranteed to be portable.

So what other options do I have, if I want to do this with standard Java 6 classes? Create a JAXB or DOM object graph just for pretty printing??

Answer

You could add the necessary code to format your document in your writeXml method. Simply maintain a depth counter (to indicate the levels of nesting). Then before you writeStartElement and after you writeEndElement use the depth index to insert an indent.

for(int x=0; x<depth; x++) {
    xmlStreamWriter.writeCharacters("    ");
}