2012-07-15 101 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

相关问题