2010-08-28 68 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