Reputation: 1103
I am wondering how the following templates work in detail. Both return the same results. Both are recursive and both use substring()
to split the string given by the calling template, but if I debug both templates, rec1
returns its string at once, while rec2
returns a value each time, it calls itself.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo style="äöb"></foo>
</root>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="#all">
<xsl:template match="foo">
<root>
<xsl:call-template name="rec1">
<xsl:with-param name="style" select="@style"/>
</xsl:call-template>
</root>
</xsl:template>
<xsl:template name="rec1">
<xsl:param name="style"/>
<xsl:variable name="firstChar" select="substring($style,1,1)"/>
<xsl:variable name="charMap">
<xsl:choose>
<xsl:when test="$firstChar='ä'">ae</xsl:when>
<xsl:when test="$firstChar='ö'">oe</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$firstChar"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="string-length($style) > 1">
<xsl:call-template name="rec1">
<xsl:with-param name="style" select="substring($style,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:value-of select="$charMap"/>
</xsl:template>
<xsl:template name="rec2">
<xsl:param name="style"/>
<xsl:variable name="firstChar" select="substring($style,1,1)"/>
<xsl:choose>
<xsl:when test="$firstChar='ä'">ae</xsl:when>
<xsl:when test="$firstChar='ö'">oe</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$firstChar"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="string-length($style) > 1">
<xsl:call-template name="rec2">
<xsl:with-param name="style" select="substring($style,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2
Views: 1008
Reputation: 1016
rec1
Template
rec1
recursively builds the value of the variable charMap
and then outputs it. The only call to <xsl:value-of select="$charMap"/>
that results in an output is the one coming from the root call of rec1
, because all subsequent recursive calls happen inside the variable definition of charMap
(<xsl:variable name=charMap>
).
Actually, <xsl:variable name="charMap">
marks the beginning of the definition of the $charMap
variable but for $charMap
to be actually defined we need to reach </xsl:variable>
… although before we reach it we enter a recursive call of rec1
! All subsequent recursive calls will find themselves waiting for the next recursive call to finish before they can define their own shorter $charMap
until we reach the last call.
In other words, for rec1
called with 'Sävsjö'
:
As long as you don't know the value of charMap5, you can't have charMap0.
rec2
Template
rec2
has no charMap
variable since each call outputs a partial result before doing the recursive call to rec2
. In the case of rec2
, no xsl:value-of
happens inside a xsl:variable
hence each xsl:value-of
produces a direct output.
Upvotes: 2