3

I am using the following code to pretty print an XML string:

private String prettyFormat(String xml) throws TransformerException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
     String formattedString = null;
     try {
         final InputSource src = new InputSource(new StringReader(xml));
         final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
         System.setProperty(DOMImplementationRegistry.PROPERTY,"com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");
         final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
         final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
         final LSSerializer writer = impl.createLSSerializer();
         writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); 
         writer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE); 
         formattedString = writer.writeToString(document); 

     } catch (Exception e) {
         throw new RuntimeException(e);
     }
   return formattedString;
}

The problem I have is that it wraps long lines so that this:

<message code="272" coeMsgName="CCR_I-Credit-Control-Initial" endtoend="AUTO" error="false" hopbyhop="AUTO" proxiable="true" request="true" retransmit="false">

becomes this:

<message code="272" coeMsgName="CCR_I-Credit-Control-Initial"
    endtoend="AUTO" error="false" hopbyhop="AUTO" proxiable="true"
    request="true" retransmit="false">
eeijlar
  • 1,232
  • 3
  • 20
  • 53
  • It seems there are no further tweaks avalable on [format-pretty-print](http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/ls/LSSerializer.html). You might instead look at rolling your own pretty printer, e.g. with no line wrap [here](http://stackoverflow.com/questions/139076/how-to-pretty-print-xml-from-java) – StuartLC Feb 05 '15 at 15:41
  • 3
    Post-processing the output might be another option. - But what is so bad about this format - it's quite pretty to me. – laune Feb 05 '15 at 15:47

2 Answers2

1

You can't. At least not when using LSSerializer, because the XMLSerializer it uses is private, and LSSerializer (and its implementation DOMSerializerImpl) don't have any method of setting the OutputFormat attribute. You can however use an XMLSerializer directly:

private static String prettyFormat(String xml) throws TransformerException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
     String formattedString = null;
     try {
         final InputSource src = new InputSource(new StringReader(xml));
         final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();

         // the last parameter sets indenting/pretty-printing to true:
         OutputFormat outputFormat = new OutputFormat("WHATEVER", "UTF-8", true);
         // line width = 0 means no line wrapping:
         outputFormat.setLineWidth(0);
         StringWriter sw = new StringWriter();
         XML11Serializer writer = new XML11Serializer(sw, outputFormat);
         writer.serialize((Element)document);
         formattedString = sw.toString(); 

     } catch (Exception e) {
         throw new RuntimeException(e);
     }
   return formattedString;
}

Result:

<message code="272" coeMsgName="CCR_I-Credit-Control-Initial" endtoend="AUTO" error="false" hopbyhop="AUTO" proxiable="true" request="true" retransmit="false">
    <test/>
</message>
Adrian Leonhard
  • 7,040
  • 2
  • 24
  • 38
  • There is just one small change needed, this line has to be changed to: `writer.serialize((Element) document);` – eeijlar Feb 05 '15 at 17:10
1

I managed to achieve this with javax.xml.transform.Transformer

public static String formatXml(Document doc) {
    try {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        StreamResult result = new StreamResult(new StringWriter());
        DOMSource source = new DOMSource(doc);
        transformer.transform(source, result);
        return result.getWriter().toString();
    } catch (ClassCastException | TransformerException | TransformerFactoryConfigurationError e) {
        throw new IllegalArgumentException("Cannot format xml", e);
    }
}
Mike
  • 20,010
  • 25
  • 97
  • 140