I have a following xml:
text
text
text
te
I think there's a much simpler and probably faster solution: you want all preceding siblings of the second divider that have at least one preceding sibling divider:
/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
It gets a bit more complex, of course, if you want to find the paras between the second and third dividers: then you want something more like Daniel Haley's solution.
Same concept as bytebuster, but a different xpath:
/*/p[count(preceding-sibling::divider)=1]
What about selecting all p
having exactly one element divider
as preceding-sibling
?
//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
Here is a general XPath expression:
/*/divider[$k]
/following-sibling::p
[count(.|/*/divider[$k+1]/preceding-sibling::p)
=
count(/*/divider[$k+1]/preceding-sibling::p)
]
If you substitute $k
with 1
then exactly the wanted p
nodes are selected.
if you substitute $k
with 2
then all p
elements between the 2nd and 3rd divider
, ..., etc.
Explanation:
This is a simple application of the Kayessian XPath 1.0 formula for node-set intersection:
$ns1[count(.|$ns2) = count($ns2)]
selects all the nodes that belong both to the nodesets $ns1
and $ns2
.
In this specific case we substitute $ns1
with:
/*/divider[$k]/following-sibling::p
and we substitute $ns2
with:
/*/divider[$k+1]/preceding-sibling::p