1

假设有 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兄弟姐妹):

  1. 对于每个level0找到具有最大值的所有“level1”节点att1(解释为Dateyyyy-mm-dd)
  2. 在这些level1节点中找到一个在年和月属性中具有最大值的节点,解释为ints。

val对于给定的示例,我希望找到具有 ="113" 值的节点。由于我不是GPath方面的专家,请帮助找到正确的 Groovish 解决方案。谢谢。

4

2 回答 2

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

然后,您可以使用“space-ship”运算符对节点进行排序进行比较,如果第一个返回 0(当比较相等时发生),则<=>使用“elvis”运算符进行下一级比较:?:

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
于 2016-08-12T03:20:14.760 回答
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}"
}
于 2016-08-11T21:03:43.103 回答