我正在使用XSLT 2.0来转换一些XML。源XML看起来类似于:
<AnimalTest>
<AnimalTypes>
<AnimalType name="cat"/>
<AnimalType name="dog"/>
</AnimalTypes>
<Animals>
<Animal name="Sylvester" typeName="cat"/>
<Animal name="Fido" typeName="dog"/>
<Animal name="Tom" typeName="cat"/>
</Animals>
</AnimalTest>
在处理AnimalType
标记的XSL模板中,我想在XPath表达式中使用name
的{{1}}属性。我能够实现这一目标的唯一方法是引入一个包含属性AnimalType
的变量,并从XPath表达式中引用,如下所示:
@name
这有效,但我想知道我是否真的必须使用这个临时变量。有没有更好的方法来引用<xsl:template match="AnimalType">
<xsl:variable name="typename" select="@name"/>
<xsl:apply-templates select="/AnimalTest/Animals/Animal[@typeName=$typename]"/>
</xsl:template>
属性?这看起来像是绕道而行。
答案 0 :(得分:3)
如果您真的不喜欢使用变量,可以使用 current()函数来引用当前上下文节点(在您的情况下为 AnimalType )
<xsl:apply-templates select="/AnimalTest/Animals/Animal[@typeName=current()/@name]"/>
如果你有一个更复杂的表达式,使用变量虽然可以提高可读性,但你可能会在其他地方重复使用。
有一点需要注意的是他的宣言
<xsl:variable name="typename" select="@name"/>
与此声明不完全相同
<xsl:variable name="typename">
<xsl:value-of select="@name" />
</xsl:variable>
虽然两个变量都包含相同的值。在后一种情况下(使用xsl:value-of),您将创建 name 属性值的副本。在前一种情况下,您直接引用该属性。因此,使用后一种格式效率会降低。
稍微提一下,您可以考虑在此处使用密钥按类型名称查找动物元素
<xsl:key name="AnimalByType" match="Animal" use="@typeName" />
这样,您的apply-templates表达式可以简化为以下
<xsl:template match="AnimalType">
<xsl:apply-templates select="key('AnimalByType', @name)"/>
</xsl:template>