Reputation: 1342
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
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
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