Rob
Rob

Reputation: 330

Groovy XmlSlurper replace node with given child node value

I'd be grateful for help with the following problem. (I am new to Groovy, and I can't find any specific examples addressing my issue).

Using XmlSlurper I am trying to replace an XML node which has a child with a certain value. For example, I want to transform:

<assets>
    <!--zero to many asset nodes beforehand-->
    <asset>
        <name>MyPackageName</name>
        <data>
            <stringValue>my string value</stringValue>
        </data>
    </asset>
    <!--zero to many asset nodes afterwards-->
</assets>

into:

<assets>
    <!--zero to many asset nodes beforehand-->
    <asset>
        <name>MyPackageName</name>
        <data/>
    </asset>
    <!--zero to many asset nodes afterwards-->
</assets>

I can't find any examples of code which navigate to find my asset with the name MyPackageName.

My failing attempt is:

    def assets = new XmlSlurper().parseText(deviceXml)
    assets.asset[name.text()=="MyPackageName"].replaceNode{
        asset{
            name("MyPackageName")
            data()
        }
    }

I get a groovy.lang.MissingPropertyException exception for a missing property for "asset" so clearly my syntax to find my node is wrong.

Upvotes: 0

Views: 9215

Answers (1)

Opal
Opal

Reputation: 84756

The following example does the job:

import groovy.xml.XmlUtil
import groovy.xml.StreamingMarkupBuilder

def input = '''<assets>
    <!--zero to many asset nodes beforehand-->
    <asset>
        <name>MyPackageName</name>
        <data>
            <stringValue>my string value</stringValue>
        </data>
    </asset>
    <!--zero to many asset nodes afterwards-->
</assets>'''

def xml = new XmlSlurper().parseText(input)

xml.asset.data.replaceNode {}

println XmlUtil.serialize(new StreamingMarkupBuilder().bind {
  mkp.yield xml
} )

The second way of updating it:

import groovy.xml.XmlUtil
import groovy.xml.StreamingMarkupBuilder

def input = '''<assets>
    <!--zero to many asset nodes beforehand-->
    <asset>
        <name>MyPackageName</name>
        <data>
            <stringValue>my string value</stringValue>
        </data>
    </asset>
    <!--zero to many asset nodes afterwards-->
</assets>'''

def assets = new XmlSlurper().parseText(input)
assets.asset.replaceNode {
    asset {
        name("MyPackageName")
        data()
    }
}

println XmlUtil.serialize(new StreamingMarkupBuilder().bind {
  mkp.yield assets
} )

With looking for a particular node:

import groovy.xml.XmlUtil
import groovy.xml.StreamingMarkupBuilder

def input = '''<assets>
    <!--zero to many asset nodes beforehand-->
    <asset>
        <name>MyPackageName</name>
        <data>
            <stringValue>my string value</stringValue>
        </data>
    </asset>
    <!--zero to many asset nodes afterwards-->
</assets>'''

def assets = new XmlSlurper().parseText(input)
assets.asset.find {it.name.text() == 'MyPackageName' }. replaceNode {
    asset {
        name("MyPackageName")
        data()
    }
}

println XmlUtil.serialize(new StreamingMarkupBuilder().bind {
  mkp.yield assets
} )

Upvotes: 3

Related Questions