Ответ 1
Такое же понятие, как bytebuster, но другое xpath:
/*/p[count(preceding-sibling::divider)=1]
У меня есть следующий xml:
<doc>
<divider />
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<divider />
<p>text</p>
<p>text</p>
<divider />
<p>text</p>
<divider />
</doc>
Я хочу выбрать все p-узлы после первого элемента делителя до следующего появления элемента divider. Я пробовал со следующим xpath:
//divider[1]/following-sibling::p[following::divider]
но проблема в том, что он выбирает все элементы p перед последним элементом разделителя. Я не уверен, как это сделать, используя xpath 1.
Такое же понятие, как bytebuster, но другое xpath:
/*/p[count(preceding-sibling::divider)=1]
Вот общее выражение XPath:
/*/divider[$k]
/following-sibling::p
[count(.|/*/divider[$k+1]/preceding-sibling::p)
=
count(/*/divider[$k+1]/preceding-sibling::p)
]
Если вы замените $k
на 1
, тогда будут выбраны именно нужные узлы p
.
если вы замените $k
на 2
, тогда все p
элементы между 2-м и 3-м divider
,... и т.д.
Объяснение
Это простое применение формулы Kayessian XPath 1.0 для пересечения node -set:
$ns1[count(.|$ns2) = count($ns2)]
выбирает все узлы, принадлежащие к узлам узлов $ns1
и $ns2
.
В этом конкретном случае подставляем $ns1
:
/*/divider[$k]/following-sibling::p
и подставим $ns2
:
/*/divider[$k+1]/preceding-sibling::p
Как выбрать все p
, имеющие ровно один элемент divider
как preceding-sibling
?
//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
Я думаю, что существует гораздо более простое и, вероятно, более быстрое решение: вы хотите, чтобы все предыдущие братья и сестры второго разделителя имели по крайней мере один предшествующий разделитель для сестер:
/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
Это немного сложнее, конечно, если вы хотите найти парас второго и третьего разделителей: тогда вам нужно что-то большее, как решение Daniel Haley.