【问题标题】:Is there a better way than xsl:variable to refer to an attribute value inside an XPath expression?有没有比 xsl:variable 更好的方法来引用 XPath 表达式中的属性值?
【发布时间】:2013-11-21 05:13:10
【问题描述】:

我正在使用 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 表达式中使用AnimalTypename 属性。我能够实现这一点的唯一方法是引入一个包含属性@name 并从 XPath 表达式内部引用的变量,如下所示:

<xsl:template match="AnimalType">
  <xsl:variable name="typename" select="@name"/>
  <xsl:apply-templates select="/AnimalTest/Animals/Animal[@typeName=$typename]"/>
</xsl:template>

这可行,但我想知道我是否真的必须使用这个临时变量。有没有更好的方法来引用 @name 属性?对我来说似乎是绕道而行。

【问题讨论】:

  • 如果您使用的是 Saxon 引擎,那么您无需担心执行速度方面的变量 - 如果只有一次调用它就会优化它。我不确定你的问题的答案,除非你已经尝试过@typeName=./@name
  • 恕我直言,这些通常用于保存搜索条件的小变量使您的源代码更具可读性。我会赞同@Vadi 的观点,即它们绝对不是性能问题。
  • @Vadi 好的,执行速度不是我首先关心的问题,但在要求一些模糊的“更好的方法”时确实需要考虑。我已经尝试过您建议的解决方案,但它不起作用。
  • @MarcusRickert 我同意 XPath 表达式本身在使用变量时更具可读性。但是,为了准确理解 XPath 表达式,必须在代码中查看更高的代码以查看分配给变量的值是多少有点不方便。

标签: xslt xslt-2.0


【解决方案1】:

如果您真的不喜欢使用该变量,您可以使用 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 属性值的副本。在前一种情况下,您直接引用属性。因此使用后一种格式效率会降低。

顺便说一句,您可以考虑在此处使用键来按类型名称查找您的 Animal 元素

<xsl:key name="AnimalByType" match="Animal" use="@typeName" />

这样,您的 apply-templates 表达式可以简化为以下内容

<xsl:template match="AnimalType">
   <xsl:apply-templates select="key('AnimalByType', @name)"/>
</xsl:template>

【讨论】:

  • 您可能会注意到,在 Saxon 中,以这种方式使用 current() 会在内部转换为您最初使用变量编写的代码。总的来说,我的审美偏好是使用变量。
  • 感谢您对我的问题及其他问题的回答教育我。 current() 方法确实对我有用。我会开始使用它,看看我喜欢它。
  • @MichaelKay 我确实在使用 Saxon,谢谢你的评论。我还没有决定我的偏好...
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多