我有以下XSLT
<xsl:key name="keyNodeUQ" match="Node" use="concat(UniqueId, '|', ../Node[@id = current()/ParentNode/@ref]/UniqueId)"/>
我要做的是创建一个键,它是节点的唯一ID,加上它父节点的唯一ID。 XML的结构如下:
<Nodes>
...
<Node id="4633">
<UniqueId>0010BAHGB</UniqueId>
<ParentNode ref="4575"/>
</Node>
<Node id="4575">
<UniqueId>K005HGBGKV</UniqueId>
</Node>
...
<Nodes>
该密钥用于基于其唯一ID发现子父级之间的唯一关系,而不是其id属性。如果我稍后尝试检查此条目是否存在:
<xsl:value-of select="count(key('keyNodeUQ', '0010BAHGB|K005HGBGKV'))"/>
我得到0.在use属性中使用current()来创建密钥是否有效?我也尝试使用。来引用上下文节点而不是当前节点,但这似乎也不起作用。任何有关如何正确构建使用声明的建议都将受到赞赏。
答案 0 :(得分:2)
用于创建密钥的use属性中的use current()是否有效?
AFAIK,是不是。 current()
是基于上下文的。密钥没有上下文。
XSLT 2.0 specification在这方面比XSLT 1.0更清晰:
[use attribute]表达式将使用与之匹配的节点进行评估 pattern作为上下文节点。
这是一个小型演示:
<强> XML 强>
<input>
<group type="Alpha" >
<item>Bravo</item>
<item>Charlie</item>
</group>
<group type="Delta" >
<item>Echo</item>
<item>Delta</item>
</group>
<group type="Foxtrot" >
<item>Golf</item>
</group>
</input>
<强> XSLT 强>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="k" match="group" use="item = current()/@type" />
<xsl:template match="/">
<output>
<xsl:copy-of select="key('k', 'true' )"/>
</output>
</xsl:template>
</xsl:stylesheet>
<强>结果强>
<output>
<group type="Delta">
<item>Echo</item>
<item>Delta</item>
</group>
</output>
答案 1 :(得分:1)
对于这种情况,我定义了一个辅助密钥,用于按id查找Node
个元素,然后在主keyNodeUQ的定义中使用它:
<xsl:key name="keyNodeId" match="Node" use="@id"/>
<xsl:key name="keyNodeUQ" match="Node"
use="concat(UniqueId, '|', key('keyNodeId', ParentNode/@ref)/UniqueId)"/>
答案 2 :(得分:0)
关于如何正确构建use语句的任何建议都会 不胜感激。
恕我直言,而不是嵌套键元素,你应该嵌套键函数 - 例如:
<xsl:key name="node-by-ref" match="Node" use="@id"/>
<xsl:key name="node-by-uid" match="Node" use="UniqueId"/>
然后:
<xsl:variable name="node-uid">0010BAHGB</xsl:variable>
<xsl:variable name="parent-uid">K005HGBGKV</xsl:variable>
<xsl:value-of select="key('node-by-ref', key('node-by-uid', $node-uid)/ParentNode/@ref)/UniqueId = $parent-uid"/>
将返回true。
或者,如果您愿意,可以这样定义键:
<xsl:key name="node-by-uid" match="Node" use="UniqueId"/>
<xsl:key name="node-by-ref|uid" match="Node" use="concat(@id, '|', UniqueId)"/>
然后使用:
<xsl:value-of select="count(key('node-by-ref|uid', concat(key('node-by-uid', $node-uid)/ParentNode/@ref, '|', $parent-uid)))"/>
答案 3 :(得分:0)
我认为你对current()的使用是合法和正确的,即使在XSLT 1.0中也是如此。
在指定current()函数时,XSLT 1.0说:“对于最外层的表达式(不在另一个表达式中出现的表达式),当前节点始终与上下文节点相同。”,并且在“当前节点“它表示当前节点不会改变,除非另有说明。
此外,在xsl:key的定义中,它表示:“当使用x作为当前节点评估xsl:key元素的use属性中指定的表达式时....”
因此,如果这不起作用,那么它看起来好像你的XSLT处理器不符合。
(好吧,你怎么办呢?理想情况下,换一个不同的处理器。但这开始是一个策略问题而不是编码问题。如果你必须解决你的XSLT处理器中的bug,那可能就是试错的问题,看哪有效。)