Iterate through EACH xml node with groovy, printing each node

27,477

The reason you keep getting the inner nodes is because you incorrectly iterate over the outer list twice. The inner loop should iterate only over tag:

doc = new XmlSlurper().parse("things.xml")
doc.thing.each { thing ->
  println "thing index: ${thing.@indexNum}"
  thing.children().each { tag ->
    println "  ${tag.name()}: ${tag.text()}"
  }
}

Output:

thing index: 1
  a: 123
  b: 456
  c: 789
thing index: 2
  a: 123
  b: 456
  c: 789
Share:
27,477
user2109043
Author by

user2109043

Updated on July 09, 2022

Comments

  • user2109043
    user2109043 almost 2 years

    I have a very simple ( I thought ) xml file like this...

    <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    
    <Things>
    <thing indexNum='1'>
      <a>123</a>
      <b>456</b>
      <c>789</c>
    </thing>
    <thing indexNum='2'>
      <a>123</a>
      <b>456</b>
      <c>789</c>
    </thing>
    </Things>
    

    The issue I'm facing is that I cannot simply get at each node separately with this code... it is printing ALL of the things, and what I'm really attempting to do is to collect each node into a map, then interrogate/transform some key/value pairs in the map and replace them (way down the road, I know..)

    Here's my horrendous code... any chance someone can set me in the right direction?

    def counter = 0
    
    Things.thing.each { tag ->
      counter++
      println "\n--------------------------------  $counter  ------------------------------------"
    
      Things.thing.children().each { tags ->
        println "$counter${tags.name()}: $tags"
        return counter
      }
      println "\n$counter things processed...\n"
    }
    

    Would it be easier to manipulate this inside of a map? (I generated this xml with a map in the first place, thinking that there would be some easy methods to work with the XML... I'm starting to wonder after goofing around for days and getting basically nowhere)

    Thanks and Regards

  • user2109043
    user2109043 over 11 years
    Thank you! I was not understanding that the first iterator name (as in { thing -> ) had to match exactly... that is why I was putting in the full path and grabbing everything twice.
  • Dave Newton
    Dave Newton over 11 years
    @user2109043 The closure parameter is each object in the collection, here, the outer tag.