XSLT调用模板递归

时间:2018-03-14 17:37:02

标签: xslt recursion

我想知道以下模板如何详细工作。两者都返回相同的结果。两者都是递归的,都使用substring()来分割调用模板给出的字符串,但是如果我调试两个模板,rec1会立即返回其字符串,而rec2每次返回一个值,它自称。

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) &gt; 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) &gt; 1">
        <xsl:call-template name="rec2">
            <xsl:with-param name="style" select="substring($style,2)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

rec1模板

rec1以递归方式构建变量charMap的值,然后输出它。对<xsl:value-of select="$charMap"/>的唯一调用导致输出是来自rec1的根调用的调用,因为所有后续递归调用都发生在charMap的变量定义内({{1} })。

实际上,<xsl:variable name=charMap>标志着<xsl:variable name="charMap">变量定义的开始,但实际定义了$charMap,我们需要达到$charMap ...但是在我们达到它之前我们输入</xsl:variable>的递归调用!所有后续的递归调用都会发现自己等待下一个递归调用完成,然后才能定义自己的短rec1,直到我们到达最后一个调用。

换句话说,对于使用$charMap调用的rec1

  • charMap0 = S + charMap1
  • charMap1 = ae + charMap2
  • charMap2 = v + charMap3
  • charMap3 = s + charMap4
  • charMap4 = j + charMap5
  • charMap5 = oe

只要您不知道 charMap5 的值,就不能拥有 charMap0

'Sävsjö'模板

rec2没有rec2变量,因为每次调用都会在对charMap进行递归调用之前输出部分结果。在rec2的情况下,rec2内不会发生xsl:value-of,因此每个xsl:variable都会产生直接输出。