Java XML Tutorial

Pretty Print XML with Java Dom and XSLT

This article shows how to use Java DOM Parser + XSLT to format or pretty print a XML document.

Table of contents

P.S Tested with Java 11

1. An XML file

staff-simple.xml

<?xml version="1.0" encoding="utf-8"?>
<company>
    <staff id="1001">
        <name>mkyong</name>
        <role>support</role>
    </staff>
    <staff id="1002">
        <name>yflow</name>
        <role>admin</role>
    </staff>
</company>

2. Pretty Print XML via Transformer

In javax.xml.transform.Transformer, we can configure the OutputKeys.INDENT property to pretty print the XML documents.


  private static void transform(Document doc, OutputStream output)
          throws TransformerException {

      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();

      // pretty print
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");

      transformer.transform(new DOMSource(doc), new StreamResult(output));

  }

Output

Terminal

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<company>

  <staff id="1001">

      <name>mkyong</name>

      <role>support</role>

  </staff>

  <staff id="1002">

      <name>yflow</name>

      <role>admin</role>

  </staff>

</company>

However, the Transformer will add many empty newlines (tested in Java 11) in the output, Not sure why?

3. Pretty Print XML via XSLT

3.1 To solve the above extra empty newlines problem, we can add an xslt file for the pretty print transformation.

staff-format.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" cdata-section-elements="cdata-other-elements"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

3.2 DOM parser example for the XSLT transformation.

XsltPrettyPrintDomParser.java

package com.mkyong.xml.dom.xslt;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

public class XsltPrettyPrintDomParser {

  private static final String XML_FILENAME
                          = "src/main/resources/staff-simple.xml";
  private static final String XSLT_FILENAME
                          = "src/main/resources/xslt/staff-format.xslt";

  public static void main(String[] args) {

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

      try (InputStream is = new FileInputStream(XML_FILENAME)) {

          DocumentBuilder db = dbf.newDocumentBuilder();

          Document doc = db.parse(is);

          transform(doc, System.out);


      } catch (IOException | ParserConfigurationException |
              SAXException | TransformerException e) {
          e.printStackTrace();
      }

  }

  private static void transform(Document doc, OutputStream output)
          throws TransformerException {

      TransformerFactory transformerFactory = TransformerFactory.newInstance();

      //Transformer transformer = transformerFactory.newTransformer();

      // add XSLT for pretty print
      Transformer transformer = transformerFactory.newTransformer(
              new StreamSource(new File(XSLT_FILENAME)));

      // pretty print, this will add extra new lines
      // transformer.setOutputProperty(OutputKeys.INDENT, "yes");

      // add extra standalone to break the root node to a new line
      transformer.setOutputProperty(OutputKeys.STANDALONE, "no");

      transformer.transform(new DOMSource(doc), new StreamResult(output));

  }

}

Output

Terminal

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<company>
  <staff id="1001">
      <name>mkyong</name>
      <role>support</role>
  </staff>
  <staff id="1002">
      <name>yflow</name>
      <role>admin</role>
  </staff>
</company>

4. Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-xml

$ cd src/main/java/com/mkyong/xml/dom/xslt/

5. References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
1 Comment
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Sasikumar
2 years ago

Hi Dude,

I have an issue while modifying XML file using Transformer API, XML declaration syntax after no new line appear. I have using open jdk 11 version. Kindly resolve the issue.