Groovy GPath通过多种条件查找节点
假设有XML:Groovy GPath通过多种条件查找节点,groovy,xml-parsing,xmlslurper,gpath,Groovy,Xml Parsing,Xmlslurper,Gpath,假设有XML: <?xml version="1.0" encoding="UTF-8"?> <data> <level0 id="2" t="1"> <level1 id="lev1id21" att1="2015-05-12" val="121" status="0" year="2015" month="05" /> <level1 id="lev1id22" att1="2015-06-13"
<?xml version="1.0" encoding="UTF-8"?>
<data>
<level0 id="2" t="1">
<level1 id="lev1id21" att1="2015-05-12" val="121" status="0" year="2015" month="05" />
<level1 id="lev1id22" att1="2015-06-13" val="132" status="0" year="2015" month="06" />
<level1 id="lev1id23" att1="2015-07-11" val="113" status="0" year="2015" month="08" />
<level1 id="lev1id23" att1="2015-07-11" val="114" status="0" year="2015" month="07" />
</level0>
</data>
我必须按条件找到level1
节点(假设我们可以有许多level0
同级节点):
level0
查找具有最大att1
值的所有“level1”节点(在yyyy-mm-dd中解释为Date
)level1
节点中,找到一个年和月属性值最大的节点,解释为int
sval
=“113”的节点。
由于我不是GPath方面的专家,请帮助我找到一个正确的Groovish解决方案。谢谢。现在我已经找到了这个解决方案,我想知道是否有更多的
Groovish
方法可以做到这一点
def xml='''<?xml version="1.0" encoding="UTF-8"?>
<data>
<level0 id="2" t="1">
<level1 id="lev1id21" att1="2015-05-12" val="121" status="0" year="2015" month="05" />
<level1 id="lev1id22" att1="2015-06-13" val="132" status="0" year="2015" month="06" />
<level1 id="lev1id23" att1="2015-07-11" val="113" status="0" year="2015" month="08" />
<level1 id="lev1id23" att1="2015-07-11" val="114" status="0" year="2015" month="07" />
</level0>
</data>'''
def nodes = new XmlSlurper().parseText(xml).level0.level1.findAll {level1 ->
level1.max {lev1->
Date.parse('yyyy-MM-dd',lev1.@att1.toString())
}
}
.each {level1 ->
level1.max { lev1 ->
lev1.@year.toString() as int
}
}.max {level1 ->
level1.@month.toString() as int
}.collect()
println "${nodes.count {it}}"
nodes.each { n ->
println "val = ${n.@val}"
}
defxml=''
'''
def nodes=new XmlSlurper().parseText(xml).level0.level1.findAll{level1->
level1.max{lev1->
parse('yyyy-MM-dd',lev1.@att1.toString())
}
}
.每个{level1->
level1.max{lev1->
lev1.@year.toString()为int
}
}.max{level1->
level1.@month.toString()为int
}.collect()
println“${nodes.count{it}”
nodes.each{n->
println“val=${n.@val}”
}
预期的行为有点不清楚,请参阅我在帖子上的评论。但是,我假设您希望按att1
,然后按年
,然后按月
对数据进行排序,并找到最大值
要以Groovy的方式进行此操作,我将提取一些帮助器方法,以便您可以看到发生了什么:
def date = { Date.parse('yyyy-MM-dd', it.@att1.toString()) }
def year = { it.@year.toString() }
def month = { it.@month.toString() }
然后,您可以使用“太空船”操作符
对节点进行排序以进行比较,如果第一个返回0,则使用“elvis”操作符?:
进行下一级比较(当比较相等时发生):
def nodes=new XmlSlurper().parseText(xml).level0.level1
def max=nodes.sort{a,b->
日期(a)日期(b)?:
年份(a)年份(b)?:
月份(a)月份(b)
}.collect{it@val}.last()
println最大值
//根据以上数据打印“113”
您的预期结果与您的标准不匹配。您想按att1
,然后按年
,然后按月
对节点进行排序吗?在这种情况下,根据您的数据,我预期结果为113
。@Codesmith_uuu谢谢,我更新了预期结果,您是对的,我预期结果为113
def nodes = new XmlSlurper().parseText(xml).level0.level1
def max = nodes.sort { a, b ->
date(a) <=> date(b) ?:
year(a) <=> year(b) ?:
month(a) <=> month(b)
} .collect { it.@val } .last()
println max
// Prints "113", given your data above