eeijlar
eeijlar

Reputation: 1342

Prevent wrapping of lines when pretty printing XML string

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">

Upvotes: 3

Views: 1771

Answers (2)

Mykhaylo Adamovych
Mykhaylo Adamovych

Reputation: 20956

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

Upvotes: 1

Adrian Leonhard
Adrian Leonhard

Reputation: 7360

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>

Upvotes: 1

Related Questions