Groovy 使用具有特定 child 计数和表达式的 xpath 查找节点
Groovy find nodes using gpath with certian child count and expression
假设我有一个 XML:
<?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),它们是:
- If
level0/@t="0"
then select this node (level0) only if all its level1
child仁有@status="0"
- If
level0/@t!="0"
then select this node (level0) only if last level1
child 有 @status="0"
。当我最后说时,我的意思是 @att1
中具有最大值的 level1
节点(假设 @att1
包含 yyyy-mm-dd
格式的日期)。
使用 XPath 我会使用像 max() 和 count() 这样的函数,但我不知道如何使用 GPath.
谢谢
Groovy 在 Iterable
上定义的 max()
和 count()
函数可以在 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 -> level1.@status != '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', level1.@att1.toString()) }?.@status == '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 ->
level0.@t == '0' ? t0Select(level0) : t1Select(level0)
}
假设我有一个 XML:
<?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),它们是:
- If
level0/@t="0"
then select this node (level0) only if all itslevel1
child仁有@status="0"
- If
level0/@t!="0"
then select this node (level0) only if lastlevel1
child 有@status="0"
。当我最后说时,我的意思是@att1
中具有最大值的level1
节点(假设@att1
包含yyyy-mm-dd
格式的日期)。
使用 XPath 我会使用像 max() 和 count() 这样的函数,但我不知道如何使用 GPath.
谢谢
Groovy 在 Iterable
上定义的 max()
和 count()
函数可以在 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 -> level1.@status != '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', level1.@att1.toString()) }?.@status == '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 ->
level0.@t == '0' ? t0Select(level0) : t1Select(level0)
}