假设有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>
我必须按条件找到level1
节点(假设我们可以有很多level0
个兄弟姐妹):
level0
找到所有“level1”节点,这些节点具有最大att1
值(在yyyy-mm-dd中解释为Date
)level1
个节点中找到一个在年和月属性中具有最大值的节点,解释为int
s。对于给定的示例,我希望找到val
=“113”值的节点。
由于我不是 GPath 的专家,请帮助找到正确的Groovish解决方案。感谢。
答案 0 :(得分:2)
预期的行为有点不清楚,请参阅我对帖子的评论。但是,我假设您希望按att1
,然后按year
,然后按month
对数据进行排序,并找到最大值。
要以Groovy方式执行此操作,我将提取一些帮助程序方法,以便您可以看到正在发生的事情:
def date = { Date.parse('yyyy-MM-dd', it.@att1.toString()) }
def year = { it.@year.toString() }
def month = { it.@month.toString() }
然后你可以使用&#34; space-ship&#34;对节点进行排序。运营商<=>
进行比较,并使用&#34; elvis&#34;如果第一个返回0(在比较相同时发生),则运算符?:
执行下一级别比较:
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
答案 1 :(得分:1)
目前我已经找到了这个解决方案,我想知道是否有更多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}"
}