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?

10 Answers 10

26

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

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));
Sign up to request clarification or add additional context in comments.

2 Comments

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 No, the "internal" version is bundled with the JRE. You can get the non-internal version by explicitly adding JAXB-RI as a dependency.
8

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

6 Comments

The link to the approach misses a colon after the https
@Josh The link is broken. This approach is proposed on SO : Formatting XML file using StAX
I added a bit more context in my answer: stackoverflow.com/a/38371920/480894
That is not answer. What transformer? How to use it?
@pavel_k docs.oracle.com/javase/7/docs/api/index.html?javax/xml/… 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
|
8

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.

Comments

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();
}

Comments

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

Comments

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

Comments

2

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);

Comments

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

Comments

0

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?

Comments

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>

1 Comment

I tried this, but when i deploy my application on weblogic and run the job it creates an xml file with &#xd; in each line after the closing tag. How to avoid this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.