我已经使用 XmlSlurper 解析了一些 html。现在我想用给定的元素名称迭代所有子元素。
我现在得到的是以下代码片段
html.'**'.findAll { it.name() == 'a' }.each {
println it
}
它有效,但还不够时髦。我想简单地写这样的东西
html.'**'.a.each {
println it
}
如果我这样做,GPath 会抱怨没有名称为“a”的属性。知道是否有一个简单的语法来制定这个迭代吗?
我已经使用 XmlSlurper 解析了一些 html。现在我想用给定的元素名称迭代所有子元素。
我现在得到的是以下代码片段
html.'**'.findAll { it.name() == 'a' }.each {
println it
}
它有效,但还不够时髦。我想简单地写这样的东西
html.'**'.a.each {
println it
}
如果我这样做,GPath 会抱怨没有名称为“a”的属性。知道是否有一个简单的语法来制定这个迭代吗?
不幸的是,目前在 Groovy 中无法执行您的要求。
当您对 GPathResult(或其任何子项)执行此类操作时
html."**".a.b.c
所做的是对每个“。” 调用GPathResult.getProperty()方法。而且这种方法只作为几个有效的语法糖(*、**、.. 和@)。这意味着,如果您不使用其中之一,则假定该属性确实存在于您所定位的每个节点。
如果您希望有一个条件空安全运算符来遍历您的树,它会请求在 GPathResult 类中添加语法糖前缀(例如 "?a" )。也许您可以使用 expando 元类并覆盖 getProperty 方法来实现,但我没有尝试过。
使用递归闭包:
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()