背景
我们正在使用启用了ngx_http_xslt_module的nginx。这将有助于我们将样式表应用于响应。
该模块在内部使用libxslt处理器来应用xslt转换。它具有可配置的递归深度(maxdepth),超过该递归将发出无限递归错误。
问题
在深度为3000时,当应用于文档时,下面的xslt转换失败并出现无限递归错误。正如我所看到的其他answers,下面的xslt模板是尾调用优化的,并且一些处理器优化了code.Wanted从xslt透视确认下面的xslt函数是否真的经过尾部优化,以及libxslt是否进行尾调用优化。
转换为代码时, escapeQuote xslt模板不是尾部调用优化的。"currentresult" + escapeQuote(sub-string(str))
以下是用于转义双引号的xslt模板。
<xsl:template name="escapeQuote">
<xsl:param name="pText" select="normalize-space(.)"/>
<xsl:if test="string-length($pText) >0">
<xsl:value-of select="substring-before(concat($pText, '"'), '"')"/>
<xsl:if test="contains($pText, '"')">
<xsl:text>\"</xsl:text>
<xsl:call-template name="escapeQuote">
<xsl:with-param name="pText" select="substring-after($pText, '"')"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
这是在XSLT 1.0中。
答案 0 :(得分:0)
libxslt
不进行尾调用优化。您应该使用libxslt
附带的EXSLT函数。 str:replace
函数在技术上不符合规范,但足以满足您的需求。具体而言(假设您尝试将"
更改为\"
):
<xsl:template xmlns:str="http://exslt.org/strings" name="escapeQuote">
<xsl:param name="pText" select="normalize-space(.)"/>
<xsl:value-of select="str:replace($pText,'"','\"')"/>
</xsl:template>
显然你可以放弃所有模板,只需插入相关的XPath,如果这对你更有效。