0

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.

Opal
  • 81,889
  • 28
  • 189
  • 210
Rob
  • 145
  • 1
  • 13

1 Answers1

3

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
} )
Opal
  • 81,889
  • 28
  • 189
  • 210
  • Sorry, maybe I have not properly explained the question. I have lots of asset nodes, with different names. I need to search for the particular name with value MyPackageName, replace the data value with an empty node, and leave the rest of the xml intact. – Rob Aug 30 '16 at 09:52
  • @Gordon, I've updated the answer. The third option seems to be what you're looking for. – Opal Aug 30 '16 at 09:56