2011-06-16 76 views
9

最好由一個簡化的例子中所示的一些具體節點:XPATH:選擇給定名稱的節點被緊接

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <A name="wrong"></A> 
    <B>not this</B> 
    <A name="right"> 
     <subA></subA> 
    </A> 
    <B>yes, this</B> <!-- I want only this one --> 
    <A name="right"> 
     <subA></subA> 
    </A> 
    <C>dont want this</C> 
    <B>not this either</B> <!-- not immediately following --> 
</root> 

我想是立即所有<B>節點以下的<A>節點與name屬性等於"right"

我嘗試什麼:

//A[@name="right"]/following-sibling::*[1] 

,其選擇緊跟在 「右」 <A>(即包括<C>)任何節點。我不知道如何使它只有<B>。這不起作用:

//A[@name="right"]/following-sibling::*[1 and B] 

這一個:

//A[@name="right"]/following-sibling::B[1] 

會後的 「右」 <A>選擇第一<B>,但不一定是緊隨之一。

+0

+1爲好問題。 – 2011-06-16 13:05:09

回答

8

你幾乎有:

//A[@name='right']/following-sibling::*[position()=1 and self::B] 

給你的樣品只有一個節點。

要引用元件名稱在某種條件下,您需要self。簡單地[B]將意味着具有文本的元素恰好等於B

+0

作品像一個魅力,謝謝! – davka 2011-06-16 11:48:46

+0

我通常會寫'// A [@ name ='right']/following-sibling :: * [1] [self :: B]' - 部分原因是爲了簡潔,部分原因是'self :: B'是一個更多在命名空間的情況下進行準確的測試。 – 2011-06-16 14:00:57

0

你可以試試這個//B[preceding-sibling::A[1][@name='right']] 這將返回節點,你有興趣

希望這有助於

+0

不強制前面的元素是'A',只是它具有適當的屬性。當我閱讀它時,你的回答並不符合要求。 – MattH 2011-06-16 10:48:34

+0

這應該按照要求! – 2011-06-17 03:45:34

+0

'// B [之前的兄弟姐妹:: A [1] [@ name ='right']]尋找第一個前面的'A'元素,而不是第一個前面的元素是'A'。 – MattH 2011-06-17 09:27:16

2

只是要指出的是,你不那麼遠,在你的問題中所示的第一個XPath:

//A[@name='right']/following-sibling::*[1][local-name()='B'] 

position()在這裏並不是不可或缺的。

+0

是不是我可以「鏈」幾個謂詞,謝謝! – davka 2011-06-16 12:56:19

+1

不客氣。這不是真的「鏈接」。您只是將謂詞應用於所選中的__first__直接跟隨節點。這是選擇一個相鄰的兄弟姐妹的常用方法。 – 2011-06-16 13:03:50