Iterate all children with a given name using GPathResult returned by XmlSlurper

Daniel Seidewitz picture Daniel Seidewitz · Sep 19, 2010 · Viewed 8.1k times · Source

I've parsed some html using XmlSlurper. Now I want to iterate all the children with a given element name.

What I've got now is the following code snippet

html.'**'.findAll { it.name() == 'a' }.each {
  println it
}

It works but just isn't groovy enough. I would like to simply write something like this

html.'**'.a.each {
  println it
}

If I do it this way, GPath complains that there is no property with name 'a'. Any idea if there is an easy syntax to formulate this iteration?

Answer

gizmo picture gizmo · Sep 22, 2010

Unfortunately, there is currently no way in Groovy to perform what you're asking.
When you perform such operation on a GPathResult (or any of its children)

html."**".a.b.c

What is done is that for each "." a call to the GPathResult.getProperty() method is made. And this method as only a few valid syntactic sugar (*, **, .. and @). This means that if you don't use one of them, it assume that the property really exist for each node you're targeting.

If you would like to have a conditional null-safe operator for traversing your tree, it would request either the addition of a syntactic sugar prefix (e.g. "?a" ) in the GPathResult class. Maybe that you can achieve that using the expando metaclass and overriding the getProperty method, but I did not try it.