XSLT: can I declare a variable globally and later assign a value to it
What can I do to make this code work?
<xsl:choose>
<xsl:when test='type = 6'>
<xsl:variable name='title' select='root/info/title' />
</xsl:when>
<xsl:when test='type = 7'>
&l开发者_如何学Got;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>
This doesn't work because when i do <xsl:value-of select='$title'/>
, $title
is out of scope. I tried to add the line <xsl:variable name='title'/>
outside of the scope, but that won't work either, because then when i call <xsl:variable name='title' select='root/info/title' />
for example, i already have set this variable before. How should I solve this?
You can move the choose inside the setting of the variable, like this:
<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>
<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>
This doesn't work
This is a FAQ:
You are defining several variables, each named $title
and each useless, because it goes out of scope immediately.
The proper way in XSLT 1.0 to define a variable based on conditions is:
<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>
Another way of defining the same variable: In this particular case you want the variable to have a string value. This can be expressed in a more compact form:
<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)))
)
"/>
Finally, in XSLT 2.0 one can define such a variable even more conveniently:
<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'
"/>
You can't re-assign variables in XSLT (1.0). The name is probably not luckily chosen; an xsl:variable
is more a symbol than a variable.
In your sample you can use the following:
<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>
Besides @carolclarinet's standar answer and more compact @Dimitre's answer, when the result depend on some node and you are worry about reuse and extensibility, you can apply templates and use pattern matching, i.e:
<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>
I'm doing it to save local value to xml xsl:desult
_document to folder /temp_variables_loop/loop-data-id_(position()).xml
.
And in next loop I read files from /temp_variables_loop.alias/loop-data-id_(position()-1).xml
.
You need to cheat xsl engine by make alias of /temp_variables_loop
to temp_variables_loop.alias
because you cannot read and write to the same file in one xsl.
Yes, you can do that in xlst 2.0, but it's forbidden in xlst 1.0 version.
the code following can run well in my pc with xslt processor saxson-he 9.8.0.12 .
<?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>
reslut of output is that:
v1 is: 123 v1 is: abcd v1 is: 234.5 map1(haha) is 119 map1(go) is 122 map1(hello) is 999
In xslt 1.0, it need recursion function, then pass the value as param.
精彩评论