2010-08-28 81 views
4

我有以下XML(实际上是HTML):的XPath子集选择

<html> 
    <h4>something</h4> 
    <p>a</p> 
    <p>b</p> 
    <h4>otherthing</h4> 
    <p>c</p> 
</html> 

可以在XPath的选择被跟随第一“H4”节点的兄弟但不是以下的兄弟姐妹的“p”的节点第二个“h4”节点(仅选择“p”节点a & b)?

+0

好问题(+1)。请参阅我的答案,了解使用通用XPath表达式进行节点集交集并检查节点是否不在给定节点集中的解决方案。 – 2010-08-28 15:21:53

回答

3

我采取

//p[preceding-sibling::h4[1] and not(preceding-sibling::h4[position() > 1])] 

找出所有p元素作为第一H4的兄弟姐妹但不是在同一轴线上的任何其他H4的兄弟姐妹

替代

//h4[1]/following-sibling::p[count(preceding-sibling::h4) = 1] 

找到的第一个H4元素的所有下列p元素那些恰好具有一个前述H4元件

+0

我认为你可以简化你的第一个答案到'/ */p [not(prior-sibling :: h4 [2])]',第二个答案放入'/ */p [count(prior-sibling :: h4)= 1]'。 – 2010-08-28 23:28:44

1

假设没有<p>第一<h4>前述,

//h4[2]/preceding-sibling::p 
+0

它不会选择第一个h4之后的兄弟姐妹,但是第二个h4之前的兄弟姐妹,这是一个差异,虽然它会产生正确的结果 – Gordon 2010-08-28 11:57:28

+0

@Gordon // h4 [1]/following-sibling :: p返回b和c。肯尼的答案是有道理的,但也需要处理只有一个h4元素的情况。 – StuartLC 2010-08-28 12:01:23

+0

@nonnb我没说没有意义。我只是说,这与问题不同。 – Gordon 2010-08-28 12:02:44

3

使用

/*/h4[1]/following-sibling::p 
      [not(count(preceding-sibling::* | /*/h4[2]) 
       = 
       count(preceding-sibling::*) 
       ) 
      ] 

更一般地,二节点集$ns1$ns2的交点是选择:

$ns1[count(.|$ns2) = count($ns2)] 

事实上,一个节点$ n不是一个节点集$ NS1由表示:

not(count($n | $ns1) = count($ns1)) 

这是一组基本的理论和标准的XPath |(联合运营商和not()功能的使用。

+0

+1集合论的调用。 – 2010-08-28 23:31:42