我发现 xsl:key 似乎不起作用的情况。
我正在将 XSLT 1 与 Xalan(已编译)一起使用,这就是发生的情况:
1.- 这有效:密钥名为test1工作正常:
<xsl:variable name="promosRTF">
<xsl:copy-of select="promo[@valid='true']"/>
</xsl:variable>
<xsl:variable name="promos" select="xalan:nodeset($promosRTF)" />
<!-- now the key: when defined and used here it works fine: -->
<xsl:key name="test1" match="//promo" use="'anytext'" />
<xsl:for-each select="key('test1','anytext')/*">
loop through elements in key... ok, works fine
</xsl:for-each>
<xsl:for-each select="$promos/*">
..loop through elements in variable $promos ...it is not empty so the loop iterates several times
</xsl:for-each>
2.- 这不起作用:关键test1现在已定义并使用(我想这是重点)在循环中迭代通过 xalan:nodeset 获得的元素
<xsl:variable name="promosRTF">
<xsl:copy-of select="promo[@valid='true']"/>
</xsl:variable>
<xsl:variable name="promos" select="xalan:nodeset($promosRTF)" />
<xsl:for-each select="$promos/*">
<!-- now the key: when defined and used (or just used) inside this for-each loop it does nothing: -->
<xsl:key name="test1" match="//promo" use="'anytext'" />
<xsl:for-each select="key('test1','anytext')/*">
loop through elements in key... NOTHING HERE, it does not work :(
</xsl:for-each>
..loop through elements in variable $promos ...it is not empty so iterates several times
</xsl:for-each>
有人知道发生了什么事吗?请注意,变量 $promos 不为空,因此循环实际上是迭代的,它是内部使用的键,它不执行任何操作。
预先非常感谢您。
PS:在马丁的回答之后,我发布了这个替代代码,它也不起作用:
<xsl:variable name="promosRTF">
<xsl:copy-of select="promo[@valid='true']"/>
</xsl:variable>
<xsl:variable name="promos" select="xalan:nodeset($promosRTF)" />
<!-- now the key: defined as a first level element: -->
<xsl:key name="test1" match="//promo" use="'anytext'" />
<xsl:for-each select="$promos/*">
<!-- but used inside this for-each loop it does nothing: -->
<xsl:for-each select="key('test1','anytext')/*">
loop through elements in key... NOTHING HERE, it does not work :(
</xsl:for-each>
..loop through elements in variable $promos ...it is not empty so iterates several times
</xsl:for-each>
解决方案:马丁的评论是问题的关键:结果树片段中的节点被视为不同文档中的节点.
马丁也指出了解决方法:在 XSLT 1.0 中,您需要使用 for-each 更改上下文节点,然后在 for-each 内调用 key。此代码将起作用:
<xsl:variable name="promosRTF">
<xsl:copy-of select="promo[@valid='true']"/>
</xsl:variable>
<xsl:variable name="promos" select="xalan:nodeset($promosRTF)" />
<!-- now the key -->
<xsl:key name="test1" match="//promo" use="'anytext'" />
<xsl:for-each select="$promos/*">
<!-- inside this for-each we are in a different *document*, so we must go back: -->
<xsl:for-each select="/">
<xsl:for-each select="key('test1','anytext')/*">
loop through elements in key... and now IT WORKS, thanks Martin :)
</xsl:for-each>
</xsl:for-each>
..loop through elements in variable $promos ...it is not empty so iterates several times
</xsl:for-each>