Groovy GPath通过多种条件查找节点

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:

<?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
    s
  • 例如,我希望找到值为
    val
    =“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