使用XmlSlurper返回的GPathResult迭代具有给定名称的所有子项

时间:2010-09-19 14:20:13

标签: groovy xmlslurper

我使用XmlSlurper解析了一些html。现在我想用给定的元素名称迭代所有子元素。

我现在得到的是以下代码段

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

它有效,但不够常规。我想简单地写一下这样的东西

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

如果我这样做,GPath抱怨没有名为'a'的属性。有没有想过是否有一个简单的语法来制定这个迭代?

2 个答案:

答案 0 :(得分:3)

不幸的是,Groovy目前无法执行您所要求的内容 在GPathResult(或其任何子级)上执行此类操作时

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

对每个“。”所做的是什么。调用GPathResult.getProperty()方法。而这种方法只有少数有效的语法糖(*,**,..和@)。这意味着如果您不使用其中一个,它会假定您要定位的每个节点都存在该属性。

如果您希望有一个条件的null-safe运算符来遍历您的树,它将要求在GPathResult类中添加一个语法糖前缀(例如“?a”)。也许您可以使用expando元类并覆盖getProperty方法来实现它,但我没有尝试过。

答案 1 :(得分:1)

使用递归闭包:

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()