В XPath 1.0 один из способов сделать это - использовать метод Кейсиана для пересечения множества узлов :
$ns1[count(.|$ns2) = count($ns2)]
Вышеприведенное выражение выбирает именно те узлы, которые являются частью набора узлов $ns1
и набора узлов $ns2
.
Чтобы применить это к конкретному вопросу - скажем, нам нужно выбрать все узлы между вторым и третьим h3
элементом в следующем XML-документе:
<html>
<h3>Title T31</h3>
<a31/>
<b31/>
<h3>Title T32</h3>
<a32/>
<b32/>
<h3>Title T33</h3>
<a33/>
<b33/>
<h3>Title T34</h3>
<a34/>
<b34/>
<h3>Title T35</h3>
</html>
Мы должны заменить $ns1
на :
/*/h3[2]/following-sibling::node()
и заменить $ns2
на :
/*/h3[3]/preceding-sibling::node()
Таким образом, полное выражение XPath равно :
/*/h3[2]/following-sibling::node()
[count(.|/*/h3[3]/preceding-sibling::node())
=
count(/*/h3[3]/preceding-sibling::node())
]
Мы можем убедиться, что это правильное выражение XPath:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/h3[2]/following-sibling::node()
[count(.|/*/h3[3]/preceding-sibling::node())
=
count(/*/h3[3]/preceding-sibling::node())
]
"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к XML-документу, представленному выше, желаемый, правильный результат выдается :
<a32/>
<b32/>
II. Решение XPath 2.0 :
Используйте оператор intersect
:
/*/h3[2]/following-sibling::node()
intersect
/*/h3[3]/preceding-sibling::node()