eXtensive Markup Language (XML) is one of the popular medium for messaging and communication between different applications. Since XML is open source and provides control over data format via DTD and XSDs, it’s widely used across technologies.
Java XML Formatter
Few days back, I came across a situation where the third party API was returning Document object and XML message as String. So I wrote this simple XmlFormatter
class to format the XML with proper indentation and convert Document object to XML String.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
package com.journaldev.java.xmlutil; 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 javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; /** * Utility Class for formatting XML * @author Pankaj * */ public class XmlFormatter { /** * * @param unformattedXml - XML String * @return Properly formatted XML String */ public String format(String unformattedXml) { try { 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) { e.printStackTrace(); return ""; } } /** * This function converts String XML to Document object * @param in - XML String * @return Document object */ 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) { e.printStackTrace(); } return null; } /** * Takes an XML Document object and makes an XML String. Just a utility * function. * * @param doc - The DOM document * @return the XML String */ public String makeXMLString(Document doc) { String xmlString = ""; if (doc != null) { try { TransformerFactory transfac = TransformerFactory.newInstance(); Transformer trans = transfac.newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); StringWriter sw = new StringWriter(); StreamResult result = new StreamResult(sw); DOMSource source = new DOMSource(doc); trans.transform(source, result); xmlString = sw.toString(); } catch (Exception e) { e.printStackTrace(); } } return xmlString; } public static void main(String args[]){ XmlFormatter formatter = new XmlFormatter(); String book = "<?xml version="1.0"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developers Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description></book><book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description></book></catalog>"; System.out.println(formatter.format(book)); } } |
To use this class, you need Apache xercesImpl.jar
that you can download from their website.
Output of the above class is a properly formatted XML String:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span style="color: #008000;"><strong><code> <?xml version="1.0" encoding="UTF-8"?> <catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developers Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description> </book> </catalog> </code></strong></span> |
I hope you will find this utility class helpful in formatting XML in Java and converting XML to Document and vice versa.
Update
It’s been many years since I wrote this article, java has evolved a lot and we can format XML string easily using javax.xml.transform
API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.journaldev.java.xmlutil; import java.io.StringReader; import java.io.StringWriter; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; /** * Utility Class for formatting XML * * @author Pankaj * */ public class XmlFormatter { public String format(String input) { return prettyFormat(input, "2"); } public static String prettyFormat(String input, String indent) { Source xmlInput = new StreamSource(new StringReader(input)); StringWriter stringWriter = new StringWriter(); try { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", indent); transformer.transform(xmlInput, new StreamResult(stringWriter)); return stringWriter.toString().trim(); } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String args[]) { XmlFormatter formatter = new XmlFormatter(); String book = "<?xml version="1.0"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developers Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description></book><book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description></book></catalog>"; System.out.println(formatter.format(book)); } } |
The output will be the same as earlier, you should use this instead of adding a dependency on any third party API.