如何使此代码正常工作?
<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' />
时,我之前已经设置了此变量。我该怎么解决这个问题?
答案 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传递。