2016-08-09 12 views
1

Предположим, у меня есть XML:Groovy найти узлы, использующие GPATH с certian ребенка считать и выражение

<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <level0 id="1" t="0"> 
     <level1 id="lev1id01" att1="2015-05-12" val="12" status="0"/> 
     <level1 id="lev1id02" att1="2015-06-13" val="13" status="0"/> 
     <level1 id="lev1id03" att1="2015-07-10" val="13" status="0"/> 
    </level0> 

    <level0 id="2" t="0"> 
     <level1 id="lev1id11" att1="2015-05-12" val="121" status="0"/> 
     <level1 id="lev1id12" att1="2015-06-13" val="132" status="0"/> 
     <level1 id="lev1id13" att1="2015-07-11" val="113" status="0"/> 
    </level0> 

    <level0 id="2" t="1"> 
     <level1 id="lev1id21" att1="2015-05-12" val="121" status="0"/> 
     <level1 id="lev1id22" att1="2015-06-13" val="132" status="0"/> 
     <level1 id="lev1id23" att1="2015-07-11" val="113" status="0"/> 
     <level1 id="lev1id23" att1="2015-07-11" val="113" status="0"/> 
    </level0> 
</data> 

Я хочу, чтобы все level0 узлы (используя GPATH), которые являются:

  1. Если level0/@t="0" затем выберите этот узел (level0), только если все его level1 c ети имеет @status="0"
  2. Если level0/@t!="0" затем выбрать этот узел (level0) только если последнийlevel1 ребенок имеет @status="0". Когда я говорю последний, я имею в виду узел level1 с максимальным значением в @att1 (при условии, что @att1 содержит дату в формате yyyy-mm-dd).

С XPath Я хотел бы использовать такие функции, как максимум() и COUNT(), но я не могу, как это может быть сделано с помощью GPATH.

Благодаря

ответ

1

В max() и count() функции, определенные Groovy на Iterable могут быть использованы в GPATH выражений вместо их эквивалентов XPath.

// This closure is for level0[t=0] elements. 
// It selects the level0 if the count of its level1[status=0] children is 0. 
def t0Select = { level0 -> 
    level0.level1.count { level1 -> [email protected] != '0' } == 0 
} 

// This closure is for level1[t=1] elements. 
// It selects the level0 if its level1 element with the maximum date has a status of "0" 
def t1Select = { level0 -> 
    level0.level1.max { level1 -> Date.parse('yyyy-MM-dd', [email protected]()) }[email protected] == '0' 
} 

// Parse the XML and delegate to the appropriate closure above as per the t attribute 
def selected = new XmlSlurper().parseText(xml).level0.findAll { level0 -> 
    [email protected] == '0' ? t0Select(level0) : t1Select(level0) 
}