0

背景

我们正在使用启用了 ngx_http_xslt_module 的 nginx。这将有助于我们将样式表应用于响应。
该模块在内部使用 libxslt 处理器来应用 xslt 转换。它具有可配置的递归深度(最大深度),超过该深度它将发出无限递归错误的信号。

问题

在深度为 3000 时,以下 xslt 转换在应用于文档时因无限递归错误而失败。根据我所看到的其他答案,以下 xslt 模板是尾调用优化的,一些处理器优化了代码。想从 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, '&quot;'), '&quot;')"/>
   <xsl:if test="contains($pText, '&quot;')">
    <xsl:text>\"</xsl:text>
    <xsl:call-template name="escapeQuote">
      <xsl:with-param name="pText" select="substring-after($pText, '&quot;')"/>
    </xsl:call-template>
   </xsl:if>
  </xsl:if>
</xsl:template>

这是在 XSLT 1.0 中。

4

1 回答 1

0

libxslt不进行尾调用优化。您应该改用libxslt. 该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,'&quot;','\&quot;')"/>
</xsl:template>

显然,您可以将模板全部丢弃,只需插入相关的 XPath,如果这对您更有效的话。

于 2017-07-05T00:13:52.437 回答