22

I have an XML document that I want to load from a file, modify a few specific elements, and then write back to disk.

I can't find any examples of how to do this in Groovy.

lospejos
  • 1,976
  • 3
  • 19
  • 35
Mike Sickler
  • 33,662
  • 21
  • 64
  • 90

4 Answers4

42

You can just modify the node's value property to modify the values of elements.

/* input:
<root>
  <foo>
    <bar id="test">
      test
    </bar>
    <baz id="test">
      test
    </baz>
  </foo>
</root>
*/

def xmlFile = "/tmp/test.xml"
def xml = new XmlParser().parse(xmlFile)
xml.foo[0].each { 
    it.@id = "test2"
    it.value = "test2"
}
new XmlNodePrinter(new PrintWriter(new FileWriter(xmlFile))).print(xml)

/* output:
<root>
  <foo>
    <bar id="test2">
      test2
    </bar>
    <baz id="test2">
      test2
    </baz>
  </foo>
</root>
*/
John Wagenleitner
  • 10,967
  • 1
  • 40
  • 39
  • 3
    This works but will mess up the formatting in your file and delete all comments. Here's an alternative that preserves formatting and comments: https://stackoverflow.com/questions/20690526/preserve-formatting-when-updating-xml-file-with-groovy#answer-20720694 – Matthias Braun Nov 27 '14 at 17:20
  • 3
    You can also preserve the format by simply pulling `new XmlNodePrinter(new PrintWriter(new FileWriter(xmlFile)))` into a variable `nodePrinter` and setting `nodePrinter.preserveWhitespace = true` before calling `print(xml)` – mikedave Feb 02 '16 at 03:08
  • 2
    For me output file is empty – Eugene Hoza Jun 08 '16 at 13:55
6

If you want to use the XmlSlurper:

//Open file
def xml = new XmlSlurper().parse('/tmp/file.xml')

//Edit File e.g. append an element called foo with attribute bar
xml.appendNode {
   foo(bar: "bar value")
}

//Save File
def writer = new FileWriter('/tmp/file.xml')

//Option 1: Write XML all on one line
def builder = new StreamingMarkupBuilder()
writer << builder.bind {
  mkp.yield xml
}

//Option 2: Pretty print XML
XmlUtil.serialize(xml, writer)

Note: XmlUtil can also be used with the XmlParser as used in @John Wagenleitner's example.

References:

Heinrich Filter
  • 5,760
  • 1
  • 33
  • 34
  • I got a similar issue in [here](https://stackoverflow.com/questions/60629223/how-to-add-an-attribute-which-contains-colonfor-xml-element-and-then-serializ).Could you help me?It's consuming my 2 days time. – aolphn Mar 11 '20 at 06:05
2

There's a pretty exhaustive set of examples for reading/writing XML using Groovy here. Regarding the loading/saving the data to/from a file, the various methods/properties that Groovy adds to java.io.File, should provide the functionality you need. Examples include:

File.write(text)
File.text
File.withWriter(Closure closure) 

See here for a complete list of these methods/properties.

Dónal
  • 185,044
  • 174
  • 569
  • 824
0

For the one who find the output empty, here is the solution:

def xml = file("${projectDir}/src/main/AndroidManifest.xml")
def manifest = new XmlSlurper().parse(file(xml))
manifest.@package = "com.newapp.id"
xml.withWriter {out->
    XmlUtil.serialize(manifest, out)
}
Afrig Aminuddin
  • 772
  • 1
  • 9
  • 22