【问题标题】:Why aren't my XSLT variables substituting their values?为什么我的 XSLT 变量没有替换它们的值?
【发布时间】:2009-03-11 12:24:55
【问题描述】:

我正在尝试使用 XSLT 变量但没有取得多大成功,希望我只是在做一些愚蠢的事情。

我有以下代码sn-p:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xalan="http://xml.apache.org/xslt"
  version="1.0">

    <xsl:template match="/">
      <xsl:variable name="config" select="query/@config"></xsl:variable>

所以我希望有一个变量 'config' 设置为我的顶级元素 'query' 的 'config' 属性的值。

我稍后会尝试在样式表中使用该变量,例如:

<a href="localhost/test?go">
    {$config}
</a>

但我在输出 HTML 文档中看到的输出是:

<a href="localhost/test?go">
    {$config}
</a>

所以该值没有像我预期的那样被替换。

我认为这几乎是最简单的情况,所以我做的很愚蠢!请帮忙,谢谢!


感谢所有回复的人,我误解了我是在属性中还是在属性之外工作的不同上下文。很好地解决了我的问题!

如果可以的话,我会接受两个答案,一个是我的答案,另一个是 @Aaron Digulla 的,它解释了属性问题。

【问题讨论】:

    标签: xslt variables substitution


    【解决方案1】:

    这里有两个问题看似相同,但有细微的不同:1) 如何按名称引用变量? 2) 在哪里可以按名称引用变量?

    首先,变量总是使用$varname 语法来引用。其次,这可以在任何允许表达的地方进行。这是第二部分似乎令人困惑。首先,元素或属性的值将默认按字面输出,因此在以下示例中实际上没有引用任何变量:

    <element attr="$test">$test or {$test}</element>
    

    输出将与输入的内容完全匹配。

    要输出变量的值,我们需要在允许表达式的地方引用它。在元素内容中,我们使用xsl:value-of;在被视为Attribute Value Template 的属性中(例如文字结果元素的属性),表达式由花括号{} 分隔。假设以下声明:

    <xsl:variable name="test" select="'value'"/>
    

    ...然后是以下内容:

    <element attr="{$test}"><xsl:value-of select="$test"/></element>
    

    ...结果:

    <element attr="value">value</element>
    

    关于 AVT 和 value-of 的一些离别说明:

    • 在这两种情况下,变量都被引用为$test。 AVT 中的大括号不是变量引用的一部分;它们是表达式分隔符。
    • 在任何一种情况下,表达式都不需要包含对变量的引用;任何 XPath 表达式都是允许的。
    • 并非 XSLT 文档中的所有属性都被视为属性值模板。例如,请注意 xsl:valueselect 属性已经接受表达式作为内容。
    • 问题:为什么不能像这样在属性中使用value-of

      <element attr="<xsl:value-of select="$test"/>"/>
      

      答案:因为 XSLT 文档必须包含格式良好的 XML(而事实并非如此)。

    • 问题:为什么不能在元素内容中使用{$varname}

      Glib 回答:因为 XSLT 的创建者不是这样设计的。

    【讨论】:

    • 看看我添加的答案:你答案中的最后一个问题/答案。不确定你是否看过这个(因为你的答案太老了)。
    • 感谢您如此清楚地解释在不同位置引用变量的不同语法。我在搜索 {} 语法的解释时发现了这一点。谢谢!
    【解决方案2】:

    在你的样式表中你必须使用:

    <xsl:value-of select="$config"/>
    

    代替:

    {$config}
    

    【讨论】:

      【解决方案3】:

      {$config} 仅适用于 XSLT 元素的属性。 (注意:大括号内有美元,因为完整的 XPath 表达式必须用大括号括起来)

      【讨论】:

      • 为什么 $ 需要在左大括号前面?没见过。
      • @divo:因为这是语法。
      • (续)“在被解释为属性值模板的属性值中 [...] 可以通过用大括号 ({}) 将表达式括起来来使用表达式。”
      • 好吧,你给我看了。我猜这就是我相信 SO 的答案所得到的。我再也不会犯这种错误了!
      • @AaronDigulla - 你对{$varname} 的语法感到困惑,因为你想错了。 $varname 是您引用变量的方式。括号分隔属性值模板,其内容甚至可能不包含变量,在这种情况下根本没有$
      【解决方案4】:

      使用&lt;xsl:value-of select="$config"/&gt; 代替{$config}

      【讨论】:

      • @Kezzer:这就是他们付给我大笔钱的原因
      【解决方案5】:

      @lwburk 的答案很棒 (+1),但最后一个问题/答案仅适用于 XSLT 1.0 和 2.0。在 3.0 中,您可以使用 TVT(Text Value Template;类似于@lwburk 的答案中提到的 AVT(属性值模板))。

      要使用 TVT,请将标准属性 xsl:expand-text="yes" 添加到元素。这将导致处理器将该元素的后代文本节点视为 TVT。

      例子:

      XSLT 3.0

      <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:output method="xml" omit-xml-declaration="yes"/>
      
          <xsl:template match="/">
              <xsl:variable name="who" select="'Dan'"/>
              <xsl:variable name="what" select="'BAM!'"/>
              <result xsl:expand-text="yes">This is {$who}'s result: {$what}</result>
          </xsl:template>
      
      </xsl:stylesheet>
      

      输出(使用任何格式正确的 XML 作为输入)

      <result>This is Dan's result: BAM!</result>
      

      注意:使用 Saxon-PE 9.5 测试。

      【讨论】:

        【解决方案6】:

        因为你需要使用&lt;xsl:value-of select="config"/&gt;

        【讨论】:

        • 如果config是一个变量,我们必须使用$config,不是吗?
        猜你喜欢
        • 1970-01-01
        • 2021-04-24
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 2014-01-28
        • 1970-01-01
        相关资源
        最近更新 更多