我正在将索引字符串转换为索引标记。该字符串可能包含多个级别,以冒号分隔。每个部分也可能有一些其他需要稍后处理的特殊符号。
我的测试字符串是"主页:更改",应转换为:
<indexterm>Home<indexterm>Change</indexterm></indexterm>
我创建了一个没有递归的模板(只做了一个嵌套级别)并且工作正常(注意在调用此模板之前添加了最外层):
<xsl:template name="parseindexstring">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains(.,':')">
<xsl:value-of select="substring-before(.,':')"/>
<indexterm>
<xsl:value-of select="substring-after(.,':')"/>
</indexterm>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
但由于我不想将处理限制在一个级别,我决定改为使用递归:
<xsl:template name="parseindexstring">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains(.,':')">
<xsl:value-of select="substring-before(.,':')"/>
<indexterm>
<xsl:call-template name="parseindexstring">
<xsl:with-param name="string" select="substring-after(.,':')"/>
</xsl:call-template>
</indexterm>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
这会进入一个无限循环,即使在只有两个级别(即只有一个冒号)的索引字符串上,我也无法找出原因。我将字符串的第二部分传递给嵌套的调用模板,但似乎总是采用顶级调用的字符串参数。至少这就是我在调试器中单步执行XSL的情况。我在这里忘记或误解了什么?
答案 0 :(得分:1)
问题是你没有在模板中使用string
参数,而是使用引用当前上下文的.
运算符(我猜的是包含输入字符串的元素) 。由于当前上下文没有变化,表达式contains(.,':')
将始终为真,并且模板只是一遍又一遍地处理相同的上下文,而不管string
设置为什么。
请尝试使用此模板:
<xsl:template name="parseindexstring">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains($string,':')">
<xsl:value-of select="substring-before($string,':')"/>
<indexterm>
<xsl:call-template name="parseindexstring">
<xsl:with-param name="string" select="substring-after($string,':')"/>
</xsl:call-template>
</indexterm>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>