开发者

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

开发者 https://www.devze.com 2023-01-17 05:14 出处:网络
I\'ve parsed some html using XmlSlurper. Now I want to iterate all the children with a given element name.

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 iter开发者_JAVA技巧ation?


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.


Use recursive closure:

def out = new StringBuffer()

def printNode
printNode = { o,node ->         
    o << '<' + node.name()
    node.attributes().each{ o << ' ' + it.key + '="' + it.value + '"' }
    o << '>'
    node.children().each{ printNode(out,it) }
    o << '</' + node.name() + '>'  
}

html.'**'.findAll { it.name() == 'a' }.each { printNode(out,it) }

println out.toString()
0

精彩评论

暂无评论...
验证码 换一张
取 消