Это невозможно сделать с помощью одного выражения XPath 1.0 .
Самое большее, что вы можете выбрать, это набор p
для данного значения @id
:
/*/a/following-sibling::div
[@id=$pId]
/preceding-sibling::p
[count(.
|
/*/a/following-sibling::div
[@id=$pId]
/preceding-sibling::div[1]
/preceding-sibling::p
)
=
count(/*/a/following-sibling::div
[@id=$pId]
/preceding-sibling::div[1]
/preceding-sibling::p
)
+1
]
Если $pId
(заменен) 2,и вышеупомянутое выражение XPath применяется к этому XML-документу (ваш XML-фрагмент обернут в верхний элемент, чтобы сделать его правильно сформированным XML-документом):
<t>
<a class="random-a-tag"></a>
<p>text1</p>
<p>text1</p>
<p>text1</p>
<div id="1"></div>
<p>text2</p>
<p>text2</p>
<p>text2</p>
<div id="2"></div>
<p>text3</p>
<p>text3</p>
<p>text3</p>
<div id="3"></div>
</t>
, затем выбираетсяследующие узлы :
<p>text2</p>
<p>text2</p>
<p>text2</p>
В приведенном выше выражении XPath мы используем хорошо известную формулу Кейсиана (созданную @Michael Kay) для пересечения множества узлов:
$ns1[count(.|$ns2) = count($ns2)]
- этопересечение наборов узлов $ns1
и $ns2
.
II.Решение XPath 2.0 :
(a/following-sibling::div
[@id=$pId]
/preceding-sibling::p
except
a/following-sibling::div
[@id=$pId]
/preceding-sibling::div[1]
/preceding-sibling::p
)/string()
Когда это выражение XPath 2.0 сравнивается с тем же XML-документом (см. Выше), а $pId
равно 2, результатом будет именно нужный текст :
text2 text2 text2