Writing Groovy’s groovy.util.Node (XmlParser) Content as XML
Groovy‘s XmlParser makes it easy to parse an XML file, XML input stream, or XML string using one its overloaded parse methods (or parseText
in the case of the String
). The XML content parsed with any of these methods is made available as a groovy.util.Node instance. This blog post describes how to make the return trip and write the content of the Node
back to XML in alternative formats such as a File
or a String
.
Groovy’s MarkupBuilder provides a convenient approach for generating XML from Groovy code. For example, I demonstrated writing XML based on SQL query results in the post GroovySql and MarkupBuilder: SQL-to-XML. However, when one wishes to write/serialize XML from a Groovy Node
, an easy and appropriate approach is to use XmlNodePrinter as demonstrated in Updating XML with XmlParser.
The next code listing, parseAndPrintXml.groovy
demonstrates use of XmlParser
to parse XML from a provided file and use of XmlNodePrinter to write that Node
parsed from the file to standard output as XML.
parseAndPrintXml.groovy : Writing XML to Standard Output
#!/usr/bin/env groovy // parseAndPrintXml.groovy // // Uses Groovy's XmlParser to parse provided XML file and uses Groovy's // XmlNodePrinter to print the contents of the Node parsed from the XML with // XmlParser to standard output. if (args.length < 1) { println "USAGE: groovy parseAndPrintXml.groovy <XMLFile>" System.exit(-1) } XmlParser xmlParser = new XmlParser() Node xml = xmlParser.parse(new File(args[0])) XmlNodePrinter nodePrinter = new XmlNodePrinter(preserveWhitespace:true) nodePrinter.print(xml)
Putting aside the comments and code for checking command line arguments, there are really 4 lines (lines 15-18) in the above code listing of significance to this discussion. These four lines demonstrate instantiating an XmlParser
(line 15), using the instance of XmlParser
to “parse” a File
instance based on a provided argument file name (line 16), instantiating an XmlNodePrinter
(line 17), and using that XmlNodePrinter
instance to “print” the parsed XML to standard output (line 18).
Although writing XML to standard output can be useful for a user to review or to redirect output to another script or tool, there are times when it is more useful to have access to the parsed XML as a String. The next code listing is just a bit more involved than the last one and demonstrates use of XmlNodePrinter
to write the parsed XML contained in an Node
instance as a Java String
.
parseXmlToString.groovy : Writing XML to Java String
#!/usr/bin/env groovy // parseXmlToString.groovy // // Uses Groovy's XmlParser to parse provided XML file and uses Groovy's // XmlNodePrinter to write the contents of the Node parsed from the XML with // XmlParser into a Java String. if (args.length < 1) { println "USAGE: groovy parseXmlToString.groovy <XMLFile>" System.exit(-1) } XmlParser xmlParser = new XmlParser() Node xml = xmlParser.parse(new File(args[0])) StringWriter stringWriter = new StringWriter() XmlNodePrinter nodePrinter = new XmlNodePrinter(new PrintWriter(stringWriter)) nodePrinter.setPreserveWhitespace(true) nodePrinter.print(xml) String xmlString = stringWriter.toString() println "XML as String:\n${xmlString}"
As the just-shown code listing demonstrates, one can instantiate an instance of XmlNodePrinter
that writes to a PrintWriter that was instantiated with a StringWriter. This StringWriter
ultimately makes the XML available as a Java String
.
Writing XML from a groovy.util.Node
to a File
is very similar to writing it to a String
with a FileWriter used instead of a StringWriter
. This is demonstrated in the next code listing.
parseAndSaveXml.groovy : Write XML to File
#!/usr/bin/env groovy // parseAndSaveXml.groovy // // Uses Groovy's XmlParser to parse provided XML file and uses Groovy's // XmlNodePrinter to write the contents of the Node parsed from the XML with // XmlParser to file with provided name. if (args.length < 2) { println "USAGE: groovy parseAndSaveXml.groovy <sourceXMLFile> <targetXMLFile>" System.exit(-1) } XmlParser xmlParser = new XmlParser() Node xml = xmlParser.parse(new File(args[0])) FileWriter fileWriter = new FileWriter(args[1]) XmlNodePrinter nodePrinter = new XmlNodePrinter(new PrintWriter(fileWriter)) nodePrinter.setPreserveWhitespace(true) nodePrinter.print(xml)
I don’t show it in this post, but the value of being able to write a Node
back out as XML often comes after modifying that Node
instance. Updating XML with XmlParser demonstrates the type of functionality that can be performed on a Node
before serializing the modified instance back out.
Reference: | Writing Groovy’s groovy.util.Node (XmlParser) Content as XML from our JCG partner Dustin Marx at the Inspired by Actual Events blog. |