What is the shortest way to pretty print a org.w3c.dom.Document to stdout?
Asked Answered
Q

6

110

What is the easiest way to pretty print (a.k.a. formatted) a org.w3c.dom.Document to stdout?

Quota answered 24/2, 2010 at 10:58 Comment(0)
M
197

Call printDocument(doc, System.out), where that method looks like this:

public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

    transformer.transform(new DOMSource(doc), 
         new StreamResult(new OutputStreamWriter(out, "UTF-8")));
}

(The indent-amount is optional, and might not work with your particular configuration)

Mishap answered 24/2, 2010 at 11:1 Comment(6)
Isn't it ironic that that's the "easiest" way to simply print an XML document in Java?Sabo
on the other hand you have plenty of control ;)Mishap
Brilliant! And yes, it is a bit much text but it is crystal clear what the selected options are and Eclipse/Netbeans really help you write this. Show me a smaller version and I tell you what it cannot do. Worse, I will tell you where you need 3 debugging rounds to get it right ...Bangka
I swear to god Java.. make me write ridiculous number of lines of code for something that can be done in one or two in other languages... with full control too..Impressionist
But if your XML contains astral characters, and you are using Xalan, note issues.apache.org/jira/browse/XALANJ-2419 and see also https://mcmap.net/q/196405/-serializing-supplementary-unicode-characters-into-xml-documents-with-javaFeckless
If you are seeing unexpected newlines in the output, take a look at https://mcmap.net/q/75268/-pretty-print-xml-in-java-8Misgovern
G
12

How about:

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(System.out, format);
serializer.serialize(doc);
Gloomy answered 19/1, 2012 at 1:6 Comment(2)
While easier, this approach requires XercesConcertino
I can add that today XMLSerializer and OutputFormat are deprecatedCota
C
10

Try jcabi-xml with one liner:

String xml = new XMLDocument(document).toString();

This is the dependency you need:

<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-xml</artifactId>
  <version>0.14</version>
</dependency>
Ciliary answered 28/8, 2013 at 19:56 Comment(0)
H
4
private void printNode(Node rootNode, String spacer) {
    System.out.println(spacer + rootNode.getNodeName() + " -> " + rootNode.getNodeValue());
    NodeList nl = rootNode.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++)
        printNode(nl.item(i), spacer + "   ");
}
Hessian answered 20/3, 2012 at 13:28 Comment(2)
I appreciate that the Q asks for the shortest, but (for the benefit of anyone else) perhaps you could elaborate your answer to explain what's going on?Heigho
html -> head -> meta -> title -> body -> If I place a space of string as the spacer above is the result is what I get. Is it what its intended to do? A full print of the XML is what is needed I think when it meants pretty printed.Greenbelt
O
0

This will return a nicely formated output by using recursive descent/ascent.

private static boolean skipNL;
private static String printXML(Node rootNode) {
    String tab = "";
    skipNL = false;
    return(printXML(rootNode, tab));
}
private static String printXML(Node rootNode, String tab) {
    String print = "";
    if(rootNode.getNodeType()==Node.ELEMENT_NODE) {
        print += "\n"+tab+"<"+rootNode.getNodeName()+">";
    }
    NodeList nl = rootNode.getChildNodes();
    if(nl.getLength()>0) {
        for (int i = 0; i < nl.getLength(); i++) {
            print += printXML(nl.item(i), tab+"  ");    // \t
        }
    } else {
        if(rootNode.getNodeValue()!=null) {
            print = rootNode.getNodeValue();
        }
        skipNL = true;
    }
    if(rootNode.getNodeType()==Node.ELEMENT_NODE) {
        if(!skipNL) {
            print += "\n"+tab;
        }
        skipNL = false;
        print += "</"+rootNode.getNodeName()+">";
    }
    return(print);
}
Odle answered 8/10, 2013 at 19:4 Comment(1)
This is very incomplete.Heigho
A
-2

if you use dom4j, it would be dom4JDOM.asString()

Azide answered 16/10, 2015 at 23:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.