Friday, November 4, 2011

Groovy, updating XML with XmlSlurper

Sometimes you don't want only to parse XML, but also modify XML with XmlSlurper.


XmlSlurper.parse(...) returns an object of type GPathResult

To change the content of a node, use replaceBody()


For instance, with the XML file of the previous post, you can change a value of an element this way:


import groovy.xml.XmlUtil

/*
 * Lookup customization file
 * Search //cus:envValueAssignments[(cus:envValueAssignments/xt:owner/xt:type/text() == $1 
 *          AND //cus:envValueAssignments/xt:owner/xt:path/text() = $2)][xt:envValueType == $3]
 * and replace their xt:value with $4
 *  
 */

def customizations = new XmlSlurper().parse("ALSBCustomizationFile.xml").declareNamespace(xt: 'http://www.bea.com/wli/config/xmltypes',xsi: 'http://www.w3.org/2001/XMLSchema-instance', cus : 'http://www.bea.com/wli/config/customizations')

//println XmlUtil.serialize( customizations )

customizations.'cus:customization'.each {
    println "UNO"
 if (it.'@xsi:type' == "cus:EnvValueCustomizationType") {
  println "TROVATO"
  for (item in it.'cus:envValueAssignments') {
   if (item.'xt:envValueType' == 'Service URI') {
    println "ITEM Service URI, before is " + item.'xt:value'
    item.'xt:value'.replaceBody("ciao")
    println "ITEM Service URI, after  is " + item.'xt:value'
   }
  }
 }
}


println XmlUtil.serialize( customizations )



The document is actually updated the second time you print it.

It was tough to figure this out, the official article on "updating XML with XmlSlurper" suggests to simply assign:

item.'xt:value' = "ciao"

but it simply doesn't work

No comments: