XslCompiledTransform因堆栈溢出而失败

时间:2013-07-08 21:33:14

标签: xslt xslcompiledtransform

我有一个包含805个模板的大型XSLT文件,根据系统和环境的不同,它会因堆栈溢出而失败。

开发环境是Windows 7,InfoPath 2010和C#。虽然安装了.NET 4.0,但此版本的InfoPath使用.NET 2.0。

使用的例程是:

private void TransformXML(String inputFileName, String transformFileName, String outputFileName)
{
    CorralLog(String.Concat("Transform with ", transformFileName, ": ", inputFileName, " -> ", outputFileName));

    using (XmlReader inputFile = XmlReader.Create(inputFileName, null))
    {
        XslCompiledTransform transform = new XslCompiledTransform(true);
        XsltSettings settings = new XsltSettings(true, false);

        transform.Load(transformFileName, settings, null);

        using(XmlWriter outputFile = XmlWriter.Create(outputFileName))
        {
            filesToDelete.Add(outputFileName);
            transform.Transform(inputFile, outputFile);
        }
    }
}

我可以看到一些可能性:

  1. 增加“变换”可用的内存。加载'命令
  2. 启动具有更多内存的单独线程
  3. 启动一个单独的线程并使用' msxsl.exe'执行转换。 (总是有效)
  4. 将XSLT文件拆分为更小的部分,并多次进行转换
  5. 有没有人有关于选择哪个选项的建议?还是其他任何建议?


    有问题的XLST文件从XML文件中获取一些元素,更改某些元素的名称,并生成另一个XML文件。大约有800个元素,每个元素都有自己的模板。

    此代码显示XSLT文件开头的三个模板和两个用于复制元素的模板:一个用于按原样复制元素,另一个用于更改元素的名称。所有后续模板都采用以下两种方式之一进行格式化。

    此语法是否导致递归,或者是导致堆栈溢出的模板数量。 (我们已经避免了这个问题,但可能没有通过在新线程中运行此转换来解决它。)

    <?xml version="1.0"?>
    
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                    xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2011-03-16T10:53:27">
    
        <xsl:output indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="/">
            <xsl:apply-templates select="*"/>
        </xsl:template>
    
        <xsl:template match="/*">
            <xsl:copy>
                <xsl:apply-templates select="*"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*">
            <xsl:apply-templates select="*"/>
        </xsl:template>
    
        <xsl:template match="/SAN/ClientProfiles/ClientProfile">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="/SAN/ClientProfiles/ClientProfile/Name">
            <CompanyName>
                <xsl:apply-templates/>
            </CompanyName>
        </xsl:template>
    

2 个答案:

答案 0 :(得分:1)

堆栈溢出的最可能原因是XSLT代码中的深度递归。我会看看相关的模板,看看它们是否可以用其他方式编写,例如使用分而治之的递归而不是头尾递归,或者可能利用XSLT 2.0 - 有一些很好的XSLT 2.0处理器用于.​​NET。

答案 1 :(得分:1)