XSLT: can I declare a variable globally and later assign a value to it
<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 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>