我想知道以下模板的详细工作原理。两者返回相同的结果。两者都是递归的,并且都使用 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) > 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>
最佳答案
<强> 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/