0

An example of the xml:

<response version-api="2.0">
    <value>
        <books>
            <book available="20" id="1" tags="">
                <title>Don Xijote</title>
                <author id="1" tags="Joel">Manuel De Cervantes</author>
            </book>
            <book available="14" id="2" tags"Jane">
                <title>Catcher in the Rye</title>
               <author id="2" tags="">JD Salinger</author>
           </book>
           <book available="13" id="3" tags="">
               <title>Alice in Wonderland</title>
               <author id="3">Lewis Carroll</author>
           </book>
           <book available="5" id="4" tags="Harry">
               <title>Don Xijote</title>
               <author id="4">Manuel De Cervantes</author>
           </book>
       </books>
   </value>
</response>

Basically I am trying to append a string value of my choosing to all attributes called "tags". This is whether the "tags" attribute has a value or not and also the attributes are at different levels of the xml structure. I have tried the method appendNode() but that spits back a groovy runtime expression error. I have also looked at this stackoverflow question but I am not getting any closer to the answer I need. This is the code:

    def rootFolder = new File('.').getCanonicalPath()
    def response = new XmlSlurper().parse(new File(rootFolder + File.separator + 'src' + File.separator + 'metadata.xml'))
    def tags = response.'**'.findAll { it['@tags']!='' }

    tags.each{ t ->
        def tagAttr =  (t.@tags.value.toString())
        println(tagAttr)
    }

Anyone have any idea on how I can achieve this?

Community
  • 1
  • 1
CommittedEel
  • 365
  • 1
  • 5
  • 14

2 Answers2

0

You nearly got it... This should do what you want (assuming I have the right end of the stick):

def xml = '''<response version-api="2.0">
            |    <value>
            |        <books>
            |            <book available="20" id="1" tags="">
            |                <title>Don Xijote</title>
            |                <author id="1" tags="Joel">Manuel De Cervantes</author>
            |            </book>
            |            <book available="14" id="2" tags="Jane">
            |                <title>Catcher in the Rye</title>
            |               <author id="2" tags="">JD Salinger</author>
            |           </book>
            |           <book available="13" id="3" tags="">
            |               <title>Alice in Wonderland</title>
            |               <author id="3">Lewis Carroll</author>
            |           </book>
            |           <book available="5" id="4" tags="Harry">
            |               <title>Don Xijote</title>
            |               <author id="4">Manuel De Cervantes</author>
            |           </book>
            |       </books>
            |   </value>
            |</response>'''.stripMargin()

import groovy.xml.*

def parsed = new XmlParser().parseText(xml)        

parsed.'**'
      .findAll { 'tags' in it.attributes().keySet().toList() }
      .each { it.@tags += (it.@tags ? ' ' : '') + 'extraTag' }

println XmlUtil.serialize(parsed)
tim_yates
  • 167,322
  • 27
  • 342
  • 338
0

You can use XmlParser (instead of XmlSlurper).

import groovy.util.XmlParser

def input = '''
<response version-api="2.0">
    <value>
        <books>
            <book available="20" id="1" tags="">
                <title>Don Xijote</title>
                <author id="1" tags="Joel">Manuel De Cervantes</author>
            </book>
            <book available="14" id="2" tags="Jane">
                <title>Catcher in the Rye</title>
               <author id="2" tags="">JD Salinger</author>
           </book>
           <book available="13" id="3" tags="">
               <title>Alice in Wonderland</title>
               <author id="3">Lewis Carroll</author>
           </book>
           <book available="5" id="4" tags="Harry">
               <title>Don Xijote</title>
               <author id="4">Manuel De Cervantes</author>
           </book>
       </books>
   </value>
</response>
'''

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

xml.'**'.findAll { if(it.@tags != null) it.@tags = it.@tags + '-hello' }

After the findAll(), the tags attributes will be modified.

Emmanuel Rosa
  • 9,697
  • 2
  • 14
  • 20