为什么我的XSLT变量不能替换它们的值?

时间:2009-03-11 12:24:55

标签: xslt variables substitution

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

我有以下代码段:

<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's,它解释了属性。

6 个答案:

答案 0 :(得分:12)

在样式表中,您必须使用:

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

而不是:

{$config}

答案 1 :(得分:12)

这里有两个看似相同的问题,但它们略有不同: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:value的{​​{1}}属性已接受表达式作为内容。
  • 问题:为什么不能在属性中使用select

    value-of

    回答:因为XSLT文档必须包含格式良好的XML(而不是)。

  • 问题:为什么不能在元素内容中使用<element attr="<xsl:value-of select="$test"/>"/>

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

答案 2 :(得分:6)

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

答案 3 :(得分:3)

使用<xsl:value-of select="$config"/>代替{$config}

答案 4 :(得分:1)

@ 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进行测试。

答案 5 :(得分:0)

因为您需要使用<xsl:value-of select="config"/>