2016-08-11 58 views
1

假設有XML:Groovy的GPATH受到許多條件的查找節點

<?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值(在yyyy-mm-dd中解釋爲Date
  2. 在這些level1節點中找到一個具有最大v年份和月份的屬性,解釋爲int s。

對於給定的例子,我期望找到具有val =「113」值的節點。 由於我不是GPath的專家,請幫助找到正確的Groovish解決方案。謝謝。

+0

您預期的結果不符合您的標準。你想按'att1',然後按'year',然後按'month'排序節點?在那種情況下,我希望給出你的數據的結果是'113'。 –

+0

@thecodesmith_謝謝,我更新了預期結果,你說得對,我希望得到113 – lospejos

回答

2

預期的行爲有點不清楚,請參閱我對帖子的評論。然而,我假設你想按att1排序數據,然後按year,然後按month,並找到最大值。

做到在一個Groovy的方式,我會提取一些輔助方法,所以你可以看到什麼是要去:

def date = { Date.parse('yyyy-MM-dd', [email protected]()) } 
def year = { [email protected]() } 
def month = { [email protected]() } 

然後你就可以使用「空間艦」的節點進行排序操作<=>做對比,並使用「貓王」運營商?:做,如果第一個返回值爲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 { [email protected] } .last() 

println max 
// Prints "113", given your data above 
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',[email protected]()) 
    } 
} 
.each {level1 -> 
    level1.max { lev1 -> 
     [email protected]() as int 
    } 
}.max {level1 -> 
    [email protected]() as int 
}.collect() 

println "${nodes.count {it}}" 

nodes.each { n -> 
    println "val = ${[email protected]}" 
}