在Saxon中处理无限递归XSL

时间:2016-04-21 00:41:48

标签: xslt saxon

我理解这个问题可能超出了Saxon,并且更多地与使用它进行转换的应用程序的体系结构相关,但只是想尝试一下。请考虑以下文件 -

XML

<?xml version="1.0" encoding="UTF-8"?>
<document>
    string
</document>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xsl xs">

    <xsl:template match="/"> 
       <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="node()">
        <xsl:apply-templates select="."/>
    </xsl:template>

</xsl:stylesheet>

XSL将在转换过程中进入无限递归,即堆栈溢出。我的问题是 - 有没有办法阻止或阻止这种类型的转换进入无限递归?可以添加到命令行的任何可以触发警告并正常停止的参数吗?

2 个答案:

答案 0 :(得分:0)

您是否尝试使用-opt:0来禁用优化?

答案 1 :(得分:0)

您可能只想创建自己的,而不是依靠现有的设置来解决这类问题。

考虑对您提供的非常简单的XML进行后续XSL 运行:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xsl xs">

    <xsl:variable name="recursion.limit" select="500" as="xs:integer"/>
    <xsl:variable name="new.line" select="'&#x0A;'" as="xs:string"/>

    <xsl:template match="/">
        <xsl:value-of select="$new.line"/>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="node()">
        <xsl:param name="recursion.count" select="1" as="xs:integer"/>

        <xsl:choose>
            <xsl:when test="$recursion.count &lt;= $recursion.limit">
                <xsl:value-of select="'&lt;' || name() || '&gt;' || ':' || $recursion.count || $new.line" disable-output-escaping="yes"/>
                <xsl:apply-templates select=".">
                    <xsl:with-param name="recursion.count" select="$recursion.count + 1" as="xs:integer"/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>
                    <xsl:value-of select="'Recursion limit of ' || $recursion.limit|| ' hit.'"/>
                </xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

这肯定会阻止或阻止这种类型的转换进入无限递归,但是它当然不是自动的。您必须在代码中进行设置。但是,如果完成,这可以用作自制的最大深度设置。此时,您要做的就是将工作表参数化以采用这样的值,而不是像我那样将其烘焙,然后进行设置。这就满足了您对可以添加到命令行的参数的需求,这些参数可以触发某种警告和/或正常停止。它是纯XSL,因此,只要您选择的引擎正确满足了XSL规范(我确实希望是Saxon),就应该与引擎无关。