我需要编写一个xpath expr来获取空节点( pb )和下一次 pb 之间的所有内容(节点和文本)。
我可以得到"一切"在 pb 节点之后,直到带有此查询的XML文件结束:
//pb/following::*|//pb/following::text()
但我想将"单身" pb到下一个pb的结果。
示例:
...
<pb/>
<elementX>text here </elementX> --|
<moreElements/> | Group 1
Plain text here without element --|
<pb/>
<elementY>text here </elementY> --| Group 2
... --|
<pb/>
... --| Group 3
EOF --|
所以我想要2 pb 之间的所有内容并将其分组。对于此示例,应该有3个结果组。第一个 pb 直到第二个的所有元素都应该在第一组中。从第二个 pb 到第三个 pb 是第二个组。从第三个 pb 到最后应该有第三组。
难以用语言描述。需要进一步的信息?
如何告诉xpath在哪里结束并对结果进行分组?
提前谢谢。答案 0 :(得分:1)
如果要创建组,XPath将不够(因为结果将始终是一个平坦的序列)。 XQuery 1.0解决方案如下所示:
for $pb in //pb
let $next-pb := $pb/following-sibling::pb[1]
return element group {
$pb/following-sibling::node()[empty($next-pb) or . << $next-pb]
}
如果您的处理器支持XQuery 3.0,您可以使用更有效的窗口子句:
declare context item := document {
<xml>
<pb/>
<elementX>text here </elementX>
<moreElements/>
Plain text here without element
<pb/>
<elementY>text here </elementY>
...
<pb/>
x
</xml>
};
for tumbling window $w in /xml/node()
start $s when name($s) = 'pb'
end $e when name(head($e/following-sibling::node())) = 'pb'
return element group { tail($w) }
答案 1 :(得分:1)
正如Christian指出的那样,XPath只能提供节点集(或节点序列),因此无法进行任何分组。在两个里程碑标记<start/>
和<end/>
之间传递节点也很棘手(但并非不可能)。在XPath 1.0中,您可以这样做:
start/following-sibling::node()[following-sibling::end]
但使用长输入序列可能效率很低。使用XQuery窗口或XSLT分组的解决方案更令人满意。