26

Is it possible using StAX (specifically woodstox) to format the output xml with newlines and tabs, i.e. in the form:

<element1>
  <element2>
   someData
  </element2>
</element1>

instead of:

<element1><element2>someData</element2></element1>

If this is not possible in woodstox, is there any other lightweight libs that can do this?

StaxMan
  • 113,358
  • 34
  • 211
  • 239
Lehane
  • 47,588
  • 14
  • 53
  • 53

10 Answers10

25

There is com.sun.xml.txw2.output.IndentingXMLStreamWriter

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));
Juha Syrjälä
  • 33,425
  • 31
  • 131
  • 183
  • as far as I can see the namespace either has an error in it or has moved to com.sun.xml.internal.txw2.output. – epeleg Sep 04 '16 at 10:10
  • @epeleg No, the "internal" version is bundled with the JRE. You can get the non-internal version by explicitly adding JAXB-RI as a dependency. – dog Oct 29 '16 at 17:19
8

Using the JDK Transformer:

public String transform(String xml) throws XMLStreamException, TransformerException
{
    Transformer t = TransformerFactory.newInstance().newTransformer();
    t.setOutputProperty(OutputKeys.INDENT, "yes");
    t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    Writer out = new StringWriter();
    t.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));
    return out.toString();
}
Roland
  • 7,525
  • 13
  • 61
  • 124
7

If you're using the StAX cursor API, you can indent the output by wrapping the XMLStreamWriter in an indenting proxy. I tried this in my own project and it worked nicely.

ewernli
  • 38,045
  • 5
  • 92
  • 123
Andrew Swan
  • 13,427
  • 22
  • 69
  • 98
7

Via the JDK: transformer.setOutputProperty(OutputKeys.INDENT, "yes");.

Josh
  • 17,834
  • 7
  • 50
  • 68
  • The link to the approach misses a colon after the https – Paul de Vrieze Nov 21 '08 at 17:16
  • 3
    @Josh The link is broken. This approach is proposed on SO : [Formatting XML file using StAX](http://stackoverflow.com/questions/2949203/formatting-xml-file-using-stax/2952945#2952945) – chepseskaf Oct 13 '11 at 08:36
  • I added a bit more context in my answer: http://stackoverflow.com/a/38371920/480894 – Roland Jul 14 '16 at 10:35
  • 3
    That is not answer. What transformer? How to use it? – Pavel_K Sep 15 '17 at 18:40
  • @pavel_k https://docs.oracle.com/javase/7/docs/api/index.html?javax/xml/transform/Transformer.html I would assume that if you are programming in Java you know how to reference Java documentation and have attempted to first implement the solution yourself – Josh Sep 15 '17 at 19:22
  • see also the OutputKeys class in the same package https://docs.oracle.com/javase/7/docs/api/index.html?javax/xml/transform/OutputKeys.html – Josh Sep 15 '17 at 19:23
4

Rather than relying on a com.sun...class that might go away (or get renamed com.oracle...class), I recommend downloading the StAX utility classes from java.net. This package contains a IndentingXMLStreamWriter class that works nicely. (Source and javadoc are included in the download.)

Thad
  • 898
  • 13
  • 24
4

How about StaxMate:

http://www.cowtowncoder.com/blog/archives/2006/09/entry_21.html

Works well with Woodstox, fast, low-memory usage (no in-memory tree built), and indents like so:


SMOutputFactory sf = new SMOutputFactory(XMLOutputFactory.newInstance());
SMOutputDocument doc = sf.createOutputDocument(new FileOutputStream("output.xml"));
doc.setIndentation("\n ", 1, 2); // for unix linefeed, 2 spaces per level    
// write doc like:    
SMOutputElement root = doc.addElement("element1");    
root.addElement("element2").addCharacters("someData");    
doc.closeRoot(); // important, flushes, closes output

Neeme Praks
  • 8,956
  • 5
  • 47
  • 47
StaxMan
  • 113,358
  • 34
  • 211
  • 239
1

If you're using the iterating method (XMLEventReader), can't you just attach a new line '\n' character to the relevant XMLEvents when writing to your XML file?

Spencer Kormos
  • 8,381
  • 3
  • 28
  • 45
1

Not sure about stax, but there was a recent discussion about pretty printing xml here

pretty print xml from java

this was my attempt at a solution

How to pretty print XML from Java?

using the org.dom4j.io.OutputFormat.createPrettyPrint() method

Community
  • 1
  • 1
mlo55
  • 361
  • 2
  • 3
1

if you are using XMLEventWriter, then an easier way to do that is:

XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLEventWriter writer = outputFactory.createXMLEventWriter(w);
        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
        Characters newLine = eventFactory.createCharacters("\n"); 
        writer.add(startRoot);
        writer.add(newLine);
Nh Wh
  • 11
  • 1
0

With Spring Batch this requires a subclass since this JIRA BATCH-1867

public class IndentingStaxEventItemWriter<T> extends StaxEventItemWriter<T> {

  @Setter
  @Getter
  private boolean indenting = true;

  @Override
  protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException {
    if ( isIndenting() ) {
      return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
    }
    else {
      return super.createXmlEventWriter( outputFactory, writer );
    }
  }

}

But this requires an additionnal dependency because Spring Batch does not include the code to indent the StAX output:

<dependency>
  <groupId>net.java.dev.stax-utils</groupId>
  <artifactId>stax-utils</artifactId>
  <version>20070216</version>
</dependency>
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • I tried this, but when i deploy my application on weblogic and run the job it creates an xml file with in each line after the closing tag. How to avoid this? – Maverick Riz Apr 23 '15 at 21:45