XSLT:我可以全局声明一个变量,然后为它赋值

时间:2010-11-17 13:49:08

标签: xslt

如何使此代码正常工作?

<xsl:choose>
  <xsl:when test='type = 6'>
    <xsl:variable name='title' select='root/info/title' />
  </xsl:when>
  <xsl:when test='type = 7'>
    <xsl:variable name='title' select='root/name' />
  </xsl:when>
  <xsl:otherwise>
    <xsl:variable name='title'>unknown</xsl:variable>
  </xsl:otherwise>
</xsl:choose>

<div class='title'>
  <xsl:value-of select='$title'/>
</div>

这不起作用,因为当我执行<xsl:value-of select='$title'/>时,$title超出范围。我尝试在范围之外添加行<xsl:variable name='title'/>,但这也不起作用,因为当我调用<xsl:variable name='title' select='root/info/title' />时,我之前已经设置了此变量。我该怎么解决这个问题?

6 个答案:

答案 0 :(得分:29)

您可以在变量设置中移动选择,如下所示:

<xsl:variable name="title">
  <xsl:choose>
    <xsl:when test='type=6'>
      <xsl:value-of select="root/info/title" />
    </xsl:when>
    ...
  </xsl:choose>
</xsl:variable>

<div class='title'>
  <xsl:value-of select="$title" />
</div>

答案 1 :(得分:11)

<xsl:choose> 
  <xsl:when test='type = 6'> 
    <xsl:variable name='title' select='root/info/title' /> 
  </xsl:when> 
  <xsl:when test='type = 7'> 
    <xsl:variable name='title' select='root/name' /> 
  </xsl:when> 
  <xsl:otherwise> 
    <xsl:variable name='title'>unknown</xsl:variable> 
  </xsl:otherwise> 
</xsl:choose> 

<div class='title'> 
  <xsl:value-of select='$title'/> 
</div> 
     

这不起作用

这是常见问题解答

您正在定义多个变量,每个变量都名为$title且每个变量都无用,因为它会立即超出范围。

XSLT 1.0中根据条件定义变量的正确方法是

<xsl:variable name="vTitle">
    <xsl:choose>
      <xsl:when test='type = 6'>
        <xsl:value-of select='root/info/title' />
      </xsl:when>
      <xsl:when test='type = 7'>
        <xsl:value-of  select='root/name' />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'unknown'"/>
      </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

定义同一变量的另一种方法:在这种特殊情况下,您希望变量具有字符串值。这可以用更紧凑的形式表达:

<xsl:variable name="vTitle2" select=
"concat(root/info/title[current()/type=6],
        root/name[current()/type=7],
        substring('unknown', 1 div (type > 7 or not(type > 5)))
       )
"/>

最后,在XSLT 2.0中,可以更方便地定义这样的变量

<xsl:variable name="vTitle3" as="xs:string" select=
 "if(type eq 6)
    then root/info/title
    else if(type eq 7)
            then root/name
            else 'unknown'
 "/>

答案 2 :(得分:3)

您无法在XSLT(1.0)中重新分配变量。这个名字可能不幸运; xsl:variable更像是一个符号,而不是一个变量。

在您的示例中,您可以使用以下内容:

<xsl:variable name='title'>
  <xsl:choose>
    <xsl:when test='type = 6'>
      <xsl:value-of select='root/info/title' />
    </xsl:when>
    <xsl:when test='type = 7'>
      <xsl:value-of select='root/name' />
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>unknown</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

答案 3 :(得分:1)

除了@ carolclarinet的标准答案和更紧凑的@Dimitre的答案,当结果依赖于某个节点并且您担心重用和可扩展性时,您可以应用模板并使用模式匹配,即:

<xsl:variable name="title"> 
    <xsl:apply-templates select="type" mode="title"/> 
</xsl:variable>

<xsl:template match="type[.=6]" mode="title"> 
    <xsl:value-of select='../root/info/title"/> 
</xsl:template> 
<xsl:template match="type[.=7]" mode="title"> 
    <xsl:value-of select='../root/name"/> 
</xsl:template> 
<xsl:template match="type" mode="title"> 
    <xsl:text>unknown</xsl:text> 
</xsl:template>

答案 4 :(得分:-1)

我这样做是为了将xml xsl:desult _ document的本地值保存到文件夹/temp_variables_loop/loop-data-id_(position()).xml

在下一个循环中,我从/ temp_variables_loop.alias/loop-data-id_(position()-1).xml读取文件。

您需要通过将/temp_variables_loop的别名设为temp_variables_loop.alias来欺骗xsl引擎,因为您无法在一个xsl中读取和写入同一文件。

答案 5 :(得分:-1)

是的,您可以在xlst 2.0中做到这一点,但是在xlst 1.0版本中是禁止的。

以下代码可以在装有xslt处理器saxson-he 9.8.0.12的PC上很好地运行。

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    exclude-result-prefixes="xs map"
    version="2.0">

    <xsl:template match="/">
        <xsl:variable name="i1" select="123" as="xs:integer"/>
        <xsl:variable name="s1" select="'abcd'" as="xs:string"/>
        <xsl:variable name="d1" select="234.5" as="xs:float"/>

        <!-- we test that variable v1 can be assignment multi times and it is ok. -->
        <xsl:variable name="v1" select="$i1"/>
        v1 is: <xsl:value-of select="$v1"/>
        <xsl:variable name="v1" select="$s1"/>
        v1 is: <xsl:value-of select="$v1"/>
        <xsl:variable name="v1" select="$d1"/>
        v1 is: <xsl:value-of select="$v1"/>

        <xsl:variable name="map1" select="map{'haha':119, 'good':110}"/>
        <xsl:variable name="map2" select="map:put($map1, 'go', 122)"/>
        <xsl:variable name="map1" select="map:put($map2, 'hello', 999)"/>
        map1(haha) is <xsl:sequence select="$map1?haha"/>
        map1(go) is <xsl:sequence select="$map1?go"/>
        map1(hello) is <xsl:sequence select="$map1?hello"/>
    </xsl:template>

</xsl:stylesheet>

输出结果是:

        v1是:123         v1是:abcd         v1是:234.5         map1(haha)是119         map1(go)是122         map1(hello)是999

在xslt 1.0中,它需要递归函数,然后将该值作为param传递。