2012-07-15 100 views
1

可變$rows具有節點的列表ID的鑰匙插入一些源XML。XSLT測試任何鍵入的節點是否存在

<row> 
    <node id="d0113" /> 
    <node id="d0237" /> 
    <node id="d0321" /> 
</row> 
<row> 
    <node id="c0278" /> 
    <node id="d0137" /> 
    <node id="e0021" /> 
</row> 

什麼是處理每個<row>之前測試的好方法,是否有任何鍵節點的實際存在的節點集合$set

所有我想出來的是

<xsl:for-each select="row"> 
    <xsl:variable name="test"> 
    <xsl:for-each select="node"> 
     <xsl:value-of select="boolean($set//*[generate-id()=current()/@id]) * 1"/> 
    </xsl:for-each>     
    </xsl:variable> 
    <xsl:if test="$test&gt;0"> 
    <!-- go ahead and process the row --> 
    </xsl:if> 
</xsl:for-each> 

回答

1
<xsl:value-of select="boolean($set//*[generate-id()=current()/@id]) * 1"/> 

這在大多數情況下返回false()所以這整個的 「索引」 的方法是不正確

這是因爲,爲generate-id() XML文檔中的任何節點的值不保證是從變換到變換相同。

即使所提供的XML文檔中生成任何node/@id屬性有第二文檔的某些特定節點上的generate-id()價值,沒有什麼可以保證在同一節點上隨之而來的新的轉型generate-id()將產生相同的VALU爲用於生成各自node/@id的那個。

建議

對於這樣的索引使用的節點的更穩定的功能 - 該功能的一個例子是XPath表達式,其選擇究竟該節點。

如果文檔不是招」被修改,即XPath表達式會始終以選擇該節點。

更新

在評論中OP堅持認爲node/@id屬性都發生在相同的變換使用。

在這種情況下,此單XPath表達式產生boolen指示$set是否包含至少一個節點,其generate-id()是另一個文檔的node/@id屬性之一:

boolean($set[generate-id() = someExpression/row/node/@id]) 

在一個test屬性可以使用一個條件指令,只是上面的參數boolean()

說明

表達:

$set[generate-id() = someExpression/row/node/@id])] 

選擇在$setgenerate-id()其值等於至少一個someExpression/row/node/@id屬性的值(someExpression這裏代表關於失蹤位置步驟中的所有節點我們什麼都不知道,因爲沒有提供XML文檔)。

根據定義,boolean($someNodeSet)總是true()如果節點集$someNodeSet至少包含一個節點,它是假的,如果$someNodeSet是空節點集。

+0

我簡化了誤導。該變量正在同一個運行中創建。所以id值保證是一樣的。我可以安全地使用generate-id。但即使使用靜態密鑰,問題也是一樣的:如何快速確定節點集是否至少包含一個節點,其ID在某個列表中出現。 (理想情況下,搜索甚至會停止,一旦發現,我的方法會進行全面掃描。) – JPM 2012-07-15 04:24:01

+0

@JPM:查看我的答案的更新。這可以在單個XPath表達式中確定,不需要'xsl:for-each'。 – 2012-07-15 04:55:42

+0

啊,是的!由於如何=與節點集一起工作。謝謝Dimitre。 +1,Q回答。 – JPM 2012-07-15 05:07:34

相關問題