类型的异常' System.OutOfMemoryException'扔进了C#

时间:2014-12-16 02:42:02

标签: c# xml xslt

我正在开发一个使用xslt将xml转换为另一个xml的应用程序。一个小的示例数据工作正常,但当它生效时,它显示类型System.OutOfMemoryException的异常。产品xml文件的大小超过600 MB。在Windows任务管理器上,它显示当应用程序内存使用量超过1.6 GB时发生崩溃。我试图增加物理内存和虚拟内存的大小。这没有用。

有什么建议吗?

C#:

// Create the XsltSettings object with document() enabled and script disabled.
    XsltSettings xsltsettings = new XsltSettings(true, false);
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(this.XsltFile, xsltsettings, new XmlUrlResolver());

    // Create the writer.
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = "\t";
    settings.OmitXmlDeclaration = true;
    settings.ConformanceLevel = ConformanceLevel.Auto;
    settings.CloseOutput = false;

    TextWriter writer = new StreamWriter(OutFile.Replace(".xml", ".txt"));
    XmlReader reader = XmlReader.Create(InFile);
    reader.MoveToContent();
    // Execute the transformation.
    xslt.Transform(reader, null, writer);
    writer.Close();
    reader.Close();

XSLT:

<xsl:stylesheet version="1.0"
                xmlns="http://www.ncr.com/rsd/WebOffice/ConfigurationManagement"
                xmlns:acm="http://www.ncr.com/rsd/WebOffice/ConfigurationManagement"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl acm">
  <xsl:output method="text" indent="no"/>

  <xsl:template match="/">
    <xsl:for-each select="/Data/Record">
      <xsl:variable  name="desc">
        <xsl:call-template name="StringReplace">
          <xsl:with-param name="text" select="desc" />
          <xsl:with-param name="replace" select='"&apos;"' />
          <xsl:with-param name="by" select='"&apos;&apos;"' />
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable  name="startdate">
        <xsl:call-template name="NumberofDays">
          <xsl:with-param name="text" select="sale_start_date"/>
        </xsl:call-template>
      </xsl:variable>  
      <xsl:variable  name="quotes">'</xsl:variable>

      <xsl:value-of select="concat('(',
        key,
        ',',
        $quotes,
        normalize-space(substring($desc, 2, string-length($desc) - 2)),
        $quotes,
        ',',       
        sale_price div 100,
        ',',
        sale_deal,
        ',',
        $startdate,
        ',',
        sale_start_time,
        ')')"/>
      <xsl:choose>
        <xsl:when test="position() = last()">;</xsl:when>
        <xsl:otherwise>,</xsl:otherwise>
      </xsl:choose>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="StringReplace">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="by"/>
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$by"/>
        <xsl:call-template name="StringReplace">
          <xsl:with-param name="text" select="substring-after($text,$replace)"/>
          <xsl:with-param name="replace" select="$replace"/>
          <xsl:with-param name="by" select="$by"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="NumberofDays">
    <xsl:param name="text"/>
    <xsl:variable name= "year" select="floor($text div 10000)"/>
    <xsl:variable name= "month" select="floor(($text mod 10000) div 100)"/>
    <xsl:variable name= "day"  select="floor(($text mod 10000) mod 100)"/>

    <xsl:choose>
      <xsl:when test="$month != 0 and $day !=0">
        <xsl:variable name= "yeardate">
          <xsl:call-template name="CalculateJulianDay">
            <xsl:with-param  name="year" select="$year"/>
            <xsl:with-param name="month" select="$month"/>
            <xsl:with-param name="day" select="$day"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:variable name= "startdate">
          <xsl:call-template name="CalculateJulianDay">
            <xsl:with-param  name="year" select="$year"/>
            <xsl:with-param name="month" select="1"/>
            <xsl:with-param name="day" select="1"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="concat($year, format-number(number($yeardate)-number($startdate)+1,'000'))" ></xsl:value-of>
      </xsl:when>
      <xsl:otherwise>0000000</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="CalculateJulianDay">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>

    <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
    <xsl:variable name="y" select="$year + 4800 - $a"/>
    <xsl:variable name="m" select="$month + 12 * $a - 3"/>

    <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 +
      floor($y div 4) - floor($y div 100) + floor($y div 400) -
      32045"/>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

的xml:

<?xml version="1.0" encoding="us-ascii"?>
<Data>
    <Record>
        <key>00000000000017</key>       
        <desc>"P&amp;G FIXTURE"</desc>       
        <sale_price>120</sale_price>
        <sale_deal>0</sale_deal>
        <sale_start_date>20121002</sale_start_date>
        <sale_start_time>0001</sale_start_time>
    </Record>
</Data>

2 个答案:

答案 0 :(得分:0)

在32位系统上,您可能会达到32位进程大小的2Gb限制

如果您转移到64位系统但继续使用32位进程,则您的应用大小限制为4Gb

在具有64位处理的64位系统上,你可以达到8T左右

答案 1 :(得分:0)

不确切知道你的xslt对象是什么,但猜测它是一个XslCompiledTransform。你见过这个:MSDN Blog Article