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

Groovy 使用XmlSlurper返回的GPathResult迭代具有给定名称的所有子级,groovy,xmlslurper,Groovy,Xmlslurper,我已经使用XmlSlurper解析了一些html。现在我想用给定的元素名迭代所有子元素 我现在得到的是以下代码片段 html.'**'.findAll{it.name(){ 打印它 } 它可以工作,但还不够好。我只想写一些这样的东西 html.'**'.a.每个{ 打印它 } 如果我这样做,GPath会抱怨没有名为“a”的属性。你知道有没有一种简单的语法来描述这个迭代吗?不幸的是,Groovy目前没有办法执行你的要求。 对GPathResult(或其任何子级)执行此类操作时 所做的是为每个“

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

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

html.'**'.findAll{it.name(){
打印它
}
它可以工作,但还不够好。我只想写一些这样的东西

html.'**'.a.每个{
打印它
}

如果我这样做,GPath会抱怨没有名为“a”的属性。你知道有没有一种简单的语法来描述这个迭代吗?

不幸的是,Groovy目前没有办法执行你的要求。
对GPathResult(或其任何子级)执行此类操作时

所做的是为每个“.”调用该方法。而这种方法只作为几个有效的语法糖(*、**、…和@)。这意味着,如果您不使用其中一个,它将假定针对每个目标节点的属性确实存在


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

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

所做的是为每个“.”调用该方法。而这种方法只作为几个有效的语法糖(*、**、…和@)。这意味着,如果您不使用其中一个,它将假定针对每个目标节点的属性确实存在

如果您希望有一个条件空安全运算符来遍历您的树,它将请求在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()
def out=new StringBuffer()
def打印节点
printNode={o,节点->
o使用递归闭包:

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()
def out=new StringBuffer()
def打印节点
printNode={o,节点->
o