How to pretty print XML from Java? How to pretty print XML from Java? xml xml

How to pretty print XML from Java?


Transformer transformer = TransformerFactory.newInstance().newTransformer();transformer.setOutputProperty(OutputKeys.INDENT, "yes");transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");// initialize StreamResult with File object to save to fileStreamResult result = new StreamResult(new StringWriter());DOMSource source = new DOMSource(doc);transformer.transform(source, result);String xmlString = result.getWriter().toString();System.out.println(xmlString);

Note: Results may vary depending on the Java version. Search for workarounds specific to your platform.


Here's an answer to my own question. I combined the answers from the various results to write a class that pretty prints XML.

No guarantees on how it responds with invalid XML or large documents.

package ecb.sdw.pretty;import org.apache.xml.serialize.OutputFormat;import org.apache.xml.serialize.XMLSerializer;import org.w3c.dom.Document;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import java.io.IOException;import java.io.StringReader;import java.io.StringWriter;import java.io.Writer;/** * Pretty-prints xml, supplied as a string. * <p/> * eg. * <code> * String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>"); * </code> */public class XmlFormatter {    public XmlFormatter() {    }    public String format(String unformattedXml) {        try {            final Document document = parseXmlFile(unformattedXml);            OutputFormat format = new OutputFormat(document);            format.setLineWidth(65);            format.setIndenting(true);            format.setIndent(2);            Writer out = new StringWriter();            XMLSerializer serializer = new XMLSerializer(out, format);            serializer.serialize(document);            return out.toString();        } catch (IOException e) {            throw new RuntimeException(e);        }    }    private Document parseXmlFile(String in) {        try {            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();            DocumentBuilder db = dbf.newDocumentBuilder();            InputSource is = new InputSource(new StringReader(in));            return db.parse(is);        } catch (ParserConfigurationException e) {            throw new RuntimeException(e);        } catch (SAXException e) {            throw new RuntimeException(e);        } catch (IOException e) {            throw new RuntimeException(e);        }    }    public static void main(String[] args) {        String unformattedXml =                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +                        "        xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +                        "        xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +                        "    <Query>\n" +                        "        <query:CategorySchemeWhere>\n" +                        "   \t\t\t\t\t         <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +                        "        </query:CategorySchemeWhere>\n" +                        "    </Query>\n\n\n\n\n" +                        "</QueryMessage>";        System.out.println(new XmlFormatter().format(unformattedXml));    }}


a simpler solution based on this answer:

public static String prettyFormat(String input, int indent) {    try {        Source xmlInput = new StreamSource(new StringReader(input));        StringWriter stringWriter = new StringWriter();        StreamResult xmlOutput = new StreamResult(stringWriter);        TransformerFactory transformerFactory = TransformerFactory.newInstance();        transformerFactory.setAttribute("indent-number", indent);        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");        Transformer transformer = transformerFactory.newTransformer();         transformer.setOutputProperty(OutputKeys.INDENT, "yes");        transformer.transform(xmlInput, xmlOutput);        return xmlOutput.getWriter().toString();    } catch (Exception e) {        throw new RuntimeException(e); // simple exception handling, please review it    }}public static String prettyFormat(String input) {    return prettyFormat(input, 2);}

testcase:

prettyFormat("<root><child>aaa</child><child/></root>");

returns:

<?xml version="1.0" encoding="UTF-8"?><root>  <child>aaa</child>  <child/></root>

//Ignore: Original edit just needs missing s in the Class name in code. redundant six characters added to get over 6 characters validation on SO