2012-07-02 27 views
3

我無法理解exsl:node-set函數的工作原理。什麼是exsl:node-set視爲根節點?

我有一些XML,我正在擴大和使用動態填充exsl:節點集。假設它現在採用以下格式:

<xsl:variable name="wrap"> 
    <nodes> 
     <node/> 
     <node/> 
     <node/> 
    </nodes> 
</xsl:variable> 
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)"/> 

這可以根據需要和輸出$ wrapNodeSet顯示上面的節點標記。根節點名稱使用名稱($ wrapNodeSet/*)顯示爲'節點'。

現在我需要擴展它以擁有2個節點並動態填充節點集。因此:

<xsl:variable name="wrap"> 
    <nodes tier="a"> 
     <node/> 
     <node/> 
     <node/> 
    </nodes> 
    <nodes tier="b"> 
     <node/> 
     <node/> 
     <node/> 
    </nodes> 
</xsl:variable> 
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)/nodes[@tier='b']"/> 

輸出節點集包括節點元素,但輸出根節點的名稱現在變爲「節點」。

有人可以解釋爲什麼節點元素仍然輸出?

回答

0

如果我已經正確地理解了你的問題,我認爲'直觀地'發生了什麼(實際的幕後實現細節可能有點不同),首先你的變量指向'匿名節點設置'包裝<nodes>元素的變量。這樣做name($wrapNodeSet/*)獲得這個匿名節點集的所有直接子節點的名稱,在這種情況下,它只是單個的<nodes>元素的名稱。

在第二種情況下,您比匿名節點集更深入,變量直接包含單個nodes[@tier='b']元素。在這種情況下,name($wrapNodeSet/*)將選擇該<nodes>元素的所有直接子元素,並將返回<node>的3個實例。如果你選擇了這個值,它將默認顯示第一個值,這就是爲什麼你會在輸出中看到「node」的原因。

要獲得第二個實例的根名稱,直接執行name($wrapNodeSet),您應該看到「節點」。在第一個實例中執行$name(wrapNodeSet)不會返回任何內容,因爲匿名節點集沒有名稱。

0
<xsl:variable name="wrapNodeSet" 
       select="exsl:node-set($wrap)/nodes[@tier='b']"/> 

這將選擇從與node-set()擴展獲得的樹中的任何nodes元件,即(所述nodes元件)具有tier屬性具有值'b'

然後:

name($wrapNodeSet/*) 

產生第一節點包含在$wrapNodeSet第一子元素的名稱。作爲$wrapNodeSet包含恰好一個nodes元件和nodes元素只有node子元素,第一個這樣的子元件是node元件和它的名稱,因爲任何node元素的名稱是"node"

爲什麼在這個結果中看到任何意想不到的事情?

換句話說

ext:node-set()的上$wrap在兩種情況下的應用程序產生的相同的樹,但是在第二種情況下使用不同的,較長的XPath表達式對ext:node-set($wrap)結果 - 因此您可以從評估這兩種不同的XPath表達式得到不同的結果。

0

exslt:節點集有一個非常非正式的規範,並且可能有關於哪些實現彼此不同的細節。在邊緣情況下這肯定是如此,例如,如果exstl:node-set的參數不是結果樹片段,則會發生什麼情況。

我期望的行爲是exslt:node-set()總是提供一個「根節點」(XPath 2.0稱爲「文檔節點」)。 XPath 1.0中定義的根節點沒有名稱。在第一個例子中,根節點有一個名爲「nodes」的元素子元素。在第二個示例中,根節點具有兩個元素子元素,它們都具有名稱「節點」。

你說「輸出根節點的名稱現在變成'node'」 - 這很混亂,因爲XPath 1.0中的「根節點」定義了從來沒有名稱的術語。你實際輸出了什麼?