XSLT 调用模板递归

标签 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>

最佳答案

<强> rec1模板

rec1递归地构建变量 charMap 的值然后输出它。唯一调用<xsl:value-of select="$charMap"/>产生的输出是来自根调用 rec1 的输出,因为所有后续递归调用都发生在 charMap 的变量定义内(<xsl:variable name=charMap>)。

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

换句话说,对于 rec1调用 'Sävsjö' :

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

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

<强> rec2模板

rec2没有charMap变量,因为每次调用在递归调用 rec2 之前都会输出部分结果。 。以rec2为例,否xsl:value-of发生在 xsl:variable 内因此每个 xsl:value-of产生直接输出。

关于XSLT 调用模板递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49284352/

相关文章:

Typescript - 类型安全深度省略,或 : how to list legal object paths

xslt - 使用 XSLT/XPath 2.0 以某种方式输出值

optimization - 函数式编程中的高效递归与不同范式中的低效递归

xml - XSLT:将单个元素的属性转换为新元素

c++ - 使用递归的非二叉树不会创建整棵树

c++ - 最大和根到叶二叉树时间复杂度

C++ 爬楼梯递归问题?

c++ - 避免并行递归异步算法中的递归模板实例化溢出

xslt - 我们可以使用 Netbeans 7 执行 XSLT 2.0 吗?

xml - 使用 XSLT 更改单个属性