Groovy Beginner Groovy Beginner - 3 months ago 20
Groovy Question

Iterate ArrayList over XML Groovy

I am iterating an arraylist over xml and creating another xml with the list of values present in arraylist. Here is the code am using

import groovy.xml.MarkupBuilder
def books='''
<response version-api="2.0">
<value>
<a>2</a>
<b>3</b>
<e>4</e>
</value>
</response>'''
def lst=["a","b","c","d"]

def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)
xml.langs {
for(String str: lst) {
def response = new XmlSlurper().parseText(books)

response.value.'*'.find{ node->
if(node.name() == str) {
"${str}"(node)
}
}
}
}
println sw


This code is working fine for the xml which does not have child nodes How to get all the child nodes of a parent which is present in the arraylist. For example if my list and input has the following

lst=["a","b","c","d"]

def books='''
<response version-api="2.0">
<value>
<a>2</a>
<b>
<e>4</e>
</b>
<g>123</g>
</value>
</response>'''


Since a and b are present in the list and node e is a part of b and g is not present in the list, the corresponding xml output should be

<response version-api="2.0">
<value>
<a>2</a>
<b>
<e>4</e>
</b>
</value>
</response>'''

Rao Rao
Answer

Here in this case, the transformed xml is almost same as input, except that node g is not present in the ouput. Using XmlParser to transform.

Here is the script which removes the particular node(all appearances).

Groovy Script

import groovy.xml.*
def books='''
    <response version-api="2.0">
        <value>
            <a>2</a>
            <b>
                <e>4</e> 
            </b>
            <g>123</g>
       </value>
    </response>'''
def elementsToBeRemoved = ['g'] 
def xml=new XmlParser().parseText(books) 
//Get all the nodes to be removed
def nodes = xml.'**'.findAll{ elementsToBeRemoved.contains(it.name())} 
//Remove all the nodes
nodes.each{it.parent().remove(it)} 
//Serialize to string
XmlUtil.serialize(xml).toString()

EDIT:

If the xml has namespaces, the following change is required.

Change from:
def nodes = xml.'**'.findAll{ it.name() == 'g' }

To:
def nodes = xml.'**'.findAll{ it.name().localPart == 'g' }

enter image description here

UPDATE2:

If you want with list of nodes to keep, then here is the simple change needed

def elementsToKeep = ["a","b","c","d"]
def nodes = xml.'**'.findAll{ !elementsToKeep.contains(it.name())}