2014-01-31 92 views
3

假設我有以下XML尋找根節點x節點的第n個實例

<root> 
    <x> 
     <y /> 
     <z> 
      <y /> 
     </z> 
     <n> 
      <m> 
       <y />* 
      </m> 
     </n> 
    </x> 
    <x> 
     <y /> 
     <z> 
      <y /> 
     </z> 
     <y />* 
    </x> 
</root> 

我想找回那些被隨後與*

Ÿ節點所以它始終是第三個節點在X祖先節點

我想是這樣的:

//x//y[3] 

但是它不工作時I g只有當y節點處於同一水平時,它纔會起作用。

所以,我想 (//x//y)[3]但整個文檔中檢索只有一個節點(第三個)

所以,我想是這樣的:

//x(//y)[3] 
//x(//y[3]) 
//x//(y[3]) 

等,但我得到解析錯誤

有什麼辦法來檢索我需要使用xpath?

回答

2

使用:

//x/descendant::y[3] 

此選擇文檔中的每一個第三y後代每個x的。有時候寫出一個擴展的表達式來看看真正發生了什麼。在這種情況下,如下:

//x//y[3] 

等同於:

/descendant-or-self::node()/child::x/descendant-or-self::node()/child::y[3] 

寫這樣,爲什麼它不會做你想要的東西,可以很明顯(即它在尋找任何y這是第三孩子x元素和沒有一個)。你真正想要的是每三分之一y後裔。這完全展開:

/descendant-or-self::node()/child::x/descendant::y[3] 

這裏最重要的教訓是,就得知道什麼XPath的abbreviated syntax真的做得。該規範實際上非常可讀。我建議看看。

1

更新:這兩個示例都只是XPath 2.0。

在XPath 1.0:

/row//y/(ancestor::x//y)[3] 

在XPath 2.0:

for $x in /row//x 
return ($x//y)[3] 
+0

XPath 1.0片段給出'無效表達式' – hek2mgl

+0

您使用的是哪種XPath引擎?我在Saxon 9.5中測試了這個表達式,並且它工作正常。它在舊版本的Saxon或Xalan中失敗。 Saxon 9.5可能將表達式評估爲XPath 2.0 ... – joemfb

+0

看起來您正在確認XPath 1.0問題。首先,當我看到這個問題時,它看起來像「易於解決」。但是,我只有xpath 1.0,我找不到方法......瘋狂,沒想到!但是,您的調查+1。可以等待XPath 2.0最終得到更廣泛的部署。 (或事實上的標準) – hek2mgl