XML parsing with Groovy


One of my mentees from Codementor had this issue with updating an XML file while preserving its original structure, whitespaces, and comments using Groovy. There were a couple of issues we ran into when working on this. XmlParser and XmlSlurper, the popular XML parsers in Groovy are both deprecated, and using them didn't preserve the original structure of the XML file when the output was saved. Here is a solution with using DOMBuilder and DOMCategory instead.

Here's the sample input XML file I am using,

in.xml:

<?xml version="1.0" encoding="UTF-8"?><meals>
    <!--Comment 1-->
    <category time="10am" type="breakfast">
        <item>Eggs</item>
        <item>Coffee</item>
    </category>
    <category time="1pm" type="lunch" >
        <!--Comment 2-->
        <item>Rice</item>
        <item>Beans</item>
    </category>
    <category time="8pm" type="dinner">
        <item>Bread</item>
        <item>Chicken</item>
    </category>
    <!--Comment 3-->
</meals>

Here's the groovy script to parse the file, update some attributes and save the updated XML to an output file while preserving the original structure, whitespaces, and comments without using deprecated XmlParser and XmlSlurper,

xml.groovy:

// Import both DOMBuilder and DOMCategory
import groovy.xml.DOMBuilder;
import groovy.xml.dom.DOMCategory;

// Convert the input XML file content to a string
def input = new File('in.xml').text

// Parse the input string using DOMBuilder
def doc = DOMBuilder.parse(new StringReader(input))

// Access the root element, which is meals
def meals = doc.documentElement

// Use DOMCategory to update values
use(DOMCategory) {
    // Get the breakfast category
    def breakfast = meals.category[0]
    // Update the breakfast category time
    breakfast['@time'] = '7am'
}

// Save the output to a file
new File('out.xml').write(meals as String)

And here's the output XML file with updates,

out.xml:

<?xml version="1.0" encoding="UTF-8"?><meals>
    <!--Comment 1-->
    <category time="7am" type="breakfast">
        <item>Eggs</item>
        <item>Coffee</item>
    </category>
    <category time="1pm" type="lunch">
        <!--Comment 2-->
        <item>Rice</item>
        <item>Beans</item>
    </category>
    <category time="8pm" type="dinner">
        <item>Bread</item>
        <item>Chicken</item>
    </category>
    <!--Comment 3-->
</meals>

References,
https://groovy-lang.org/processing-xml.html
https://community.smartbear.com/t5/API-Functional-Security-Testing/Sharing-is-caring-how-to-modify-xml-files-using-ReadyApi/m-p/168661

Comments