我有以下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>
我想在第一个divider元素之后选择所有p个节点,直到下一次出现divider元素。我试着跟随xpath:
//divider[1]/following-sibling::p[following::divider]
但问题是它在最后一个divider元素之前选择所有p个元素。我不确定如何使用xpath 1。
答案 0 :(得分:28)
与bytebuster相同的概念,但是不同的xpath:
/*/p[count(preceding-sibling::divider)=1]
答案 1 :(得分:19)
这是一般的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公式的简单应用:
$ns1[count(.|$ns2) = count($ns2)]
选择属于两者的所有节点到节点集$ns1
和$ns2
。
在这种特定情况下,我们将$ns1
替换为:
/*/divider[$k]/following-sibling::p
我们将$ns2
替换为:
/*/divider[$k+1]/preceding-sibling::p
答案 2 :(得分:5)
选择具有完全一个元素p
的所有divider
作为preceding-sibling
呢?
//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
答案 3 :(得分:5)
我认为有一个更简单且可能更快的解决方案:您希望第二个分频器的所有前面的兄弟姐妹至少有一个前一个兄弟分频器:
/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
当然,如果你想找到第二个和第三个分隔线之间的差距,它会变得有点复杂:那么你想要更像Daniel Haley的解决方案。