2009-05-21 51 views
9

選擇第一個結果我看這個問題:Select first instance only with XPath?XPath中

但是,如果我有一個節點集是這樣的:


<container value=""> 
    <data id="1"></data> 
    <data id="2">test</data> 
    <container> 
    <data id="1">test</data> 
    <data id="3">test</data> 
    </container> 
</container> 

現在我的情況是,這個節點集是深在文檔中,我有一個指向內部容器的指針。所以我必須在我的XPath前面加上「/ container/container」(路徑實際上更長,但是對於這個例子應該這樣做)。

編輯: 我想要的是一個id爲1的「數據」節點,它應該來自最低節點的第一個或最近的祖先。因此,如果我無法在「當前」(/容器/容器)上找到它,我應該查看祖先並獲取最近的一個(或者最終找不到任何東西)。我曾嘗試這樣的:

/容器/容器/祖先或自::容器/數據[@ ID = 「1」]

這使背面具有兩個節點的結果集。我以爲我可以用last()來獲得最深的那個,所以我在最後加上了這個,但無濟於事。

+0

說明書可以更清楚做。你想要數據節點?數據節點必須具有1的ID?如果數據節點的ID不是1,則想要將文檔向上移動到父容器,以查看該數據節點是否具有ID爲1的數據節點,如果不一直持續直到具有ID的數據節點找到1。這是否描述了它? – AnthonyWJones 2009-05-21 12:01:05

+0

我試圖描述我在尋找更清晰的東西,儘管有些人猜測它。抱歉! – 2009-05-21 12:43:05

回答

5

你怎麼嘗試最後一個()上套結?我想,這應該工作:

/container/container/ancestor-or-self::container/data[@id="1"][last()] 

編輯:

權,當然,我忘了括號:

(/container/container/ancestor-or-self::container/data[@id="1"])[last()] 

這使得這個一樣的其他的答案之一;但是,由於原來的海報指出,這種表達失敗的:

<container value=""> 
    <container> 
    <data id="1">a3</data> 
    <data id="3">a4</data> 
    </container> 
    <data id="1">a1</data> 
    <data id="2">a2</data> 
</container> 

真到計算器的精神,我可以然而與其他的答案中的一個結合我的答案,得到的東西,在所有情況下工作:

(/container/container/ancestor-or-self::container[data[@id="1"]])[last()]/data[@id="1"] 

順便說一下,如果有多個@ id-is-1 <數據>一個容器的子元素,這將返回所有元素。只返回第一個這樣的<數據>元素:

(/container/container/ancestor-or-self::container[data[@id="1"]])[last()]/data[@id="1"][1] 
+0

如果我在這裏閱讀期望的結果是正確的(大)如果這是行不通的,因爲last()會匹配祖先或自我的兩個分支 - 這就是真正的問題,所以你需要提前(如我)或遲到(如Dave所做的那樣)剪輯結果集。 – annakata 2009-05-21 11:55:02

1

我對你的要求不明確的100%,但如果我沒有理解錯的,也許你只是想:

/container/container/ancestor-or-self::container[1]/data[@id='1'] 

標註「[1]」

編輯:想過這個問題更多一點,以下爲我工作的所有情況,到目前爲止尋找@ ID = $ N

/container/container/ancestor-or-self::container[data[@id=$N]][1]/data[@id=$N] 

非常極端xpathing那裏。基本上,發生的事情是來自祖先或自我的節點集返回位置1處的最低順序 - 這就是你想要的順序 - 但是你需要在其上添加第二個條件,該節點也有你感興趣的數據節點,一旦你滿足了這些條件,你現在就擁有了正確的節點,你只是想進一步深入到實際的數據。如果你把它拆開,並把它作爲一種算法:)時間的XPath

99%變得更容易

+0

我嘗試過,但並不包括每一個案例。如果我正在尋找@ id ='2'怎麼辦?我希望在祖先之前支持當前節點的結果,但能夠回退。 – 2009-05-21 18:32:45

+0

查看編輯:我相信涵蓋了所有列出的案例 – annakata 2009-05-22 07:51:43

0

而不是

@id="1" 

你嘗試過:

position() == 1 
11

確保last()正確作用域。嘗試:

(/container/container/ancestor-or-self::container/data[@id="1"])[last()] 

同理:

//container[last()] 

和:

(//container)[last()] 

是不一樣的東西。第一個將返回層次結構中每個級別的最後一個容器節點 - 多個匹配 - 第二個將返回找到的最後一個容器節點 - 一個匹配。

0

嘗試 [位置()= 1]

離。

/容器/容器/祖先或自::容器/數據[位置()= 1]