2015-10-17 149 views
2

考慮下面的標記。在這種情況下,我以下節點之後我:選擇所有節點,直到一個特定的給定節點/標籤

<dd>A</dd> 
<dd>B</dd> 
<dd>C</dd> 

我想下面的XPath代碼,但預期它不工作。

xpath("//div[@id='about']/dl/dt[contains(text(),'Names')]/following-sibling::dd[not(following-sibling::dt)]/text()") 

有關如何解決它的任何想法?

非常感謝。

回答

3

更新:更簡單的解決

。在你的情況的一個先決條件,那就是錨項目始終是第一個前置兄弟具有一定的財產。正因爲如此,這裏的寫作以下複雜表達式的一個更簡單的方法:

/div/dl/dd[preceding-sibling::dt[1][. = 'Names']] 

換句話說:

  • 選擇任何dd
  • 具有第一前置兄弟dt(前面的兄弟軸向後計數)
  • 其本身具有「名稱」的值

從oXygen的以下屏幕截圖可以看出,它選擇您想要選擇的節點(如果將「名稱」更改爲「狀態」或「另一個字段」,它將在下一個dt之前選擇僅以下幾個節點也)。

screenshot from oXygen of selected nodes

原本複雜的解決方案(留下供參考)

這是XPath 2.0中更容易,但是讓我們假設你只能使用XPath 1.0。訣竅在於計算來自錨元素(其中包含「名稱」的元素)中前一個兄弟元素的數量,並忽略任何錯誤數量的元素(即,當我們跨過<dt>Status</dt>時,前面的兄弟元素數量增加) 。

對於XPath 1.0中,除去(::)之間的意見(XPath中,空白是無關緊要的,你可以把它的可讀性多的XPath,但在1.0,評論是不可能的)

/div/dl/dd 

    (: any dd having a dt before it with "Names" :) 
    [preceding-sibling::dt[. = 'Names']] 

    (: count the preceding siblings up to dt with "Names", add one to include 'self' :) 
    [count(preceding-sibling::dt[. = 'Names']/preceding-sibling::dt) + 1 
    = 

    (: compare with count of all preceding siblings :) 
    count(preceding-sibling::dt)] 

由於一行:

/div/dl/dd[preceding-sibling::dt[. = 'Names']][count(preceding-sibling::dt[. = 'Names']/preceding-sibling::dt) + 1 = count(preceding-sibling::dt)] 
+0

感謝您的解釋。試圖瞭解它:) –

+0

@安德烈,很高興我能有一定的幫助! :) – Abel

0

如何:

//dd[preceding-sibling::dt[contains(., 'Names')]][following-sibling::dt] 
+0

沒有。這將返回所有''

以下'
名稱
':'
一個
Ç
'。 –

+0

我用'oXygen'編輯器執行這個表達式,它給了我預期的結果。 '

'不應該出現在結果中。這個元素沒有後面的兄弟'
'。 – Kachna

+0

哦,我明白了。你是對的。但我已經更新了標記在原來的問題,以滿足另一種情況,其中有'

另一場
'。現在您的代碼將在''返回
,對不對? –

相關問題