I have a xml document like follows,
<sec>
<p type="Running">aa</p>
<p type="heading 1">bb</p>
<p type="body">cc</p>
<p type="body">dd</p>
<p type="Running">ee</p>
<p type="Body">ff</p>
<p type="heading">gg</p>
<p type="body">hh</p>
<p type="body">ii</p>
<p type="Running">jj</p>
<p type="list">kk</p>
<p type="list">ll</p>
<p type="list">mm</p>
<p type="list">nn</p>
</sec>
using xpath I need to select consecutive following-siblings of <p>
nodes from <p>
that has attr value of Running
.
SO in above example
<p type="heading 1">bb</p>
<p type="body">cc</p>
<p type="body">dd</p>
and
<p type="Body">ff</p>
<p type="heading">gg</p>
<p type="body">hh</p>
<p type="body">ii</p>
and
<p type="list">kk</p>
<p type="list">ll</p>
<p type="list">mm</p>
<p type="list">nn</p>
node groups should be selected.
How can I write a XPath query to select those nodes?
XPath version - 2.0
This question currently has three answers, but I don't think any of them actually answers the question.
In XPath 2.0, everything is sequences. If you select a set of nodes, in XPath 1.0 you called that a "node set", in XPath 2.0 it is a "sequence of nodes". One property of sequences is that they cannot be nested:
(1, (2, 3), 4)
is the same as(1, 2, 3, 4)
.You ask for a select statement that selects sets of nodes, which implies that you want to do something with each set. The logical thing to do is something like the following:
This is a rather complex expression. While it will internally select the subsets you are after, because of sequence normalization, the net effect is a single sequence with a selection equal to
sec/p[not(@type = 'Running')]
.In XPath 2.0 it is not possible to do this differently, so the natural thing to do then is to use a host language, like XSLT or XQuery, to select the
@type = 'Running'
nodes, and on each hit, select (and do something) will the following siblings until the next@type = 'Running'
:It is probably easier to use an
xsl:for-each-group
here, which is meant for this kind of thing.I don't know XPath 2, but with XPath 1 and a bit of higher-level programming, you can use this kind of XPath expressions, counting preceding siblings with type="Running":
Below Xpath select everything except type='Running'
This should help you -