我正在开发一个使用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='"'"' />
<xsl:with-param name="by" select='"''"' />
</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>
</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&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>
答案 0 :(得分:0)
在32位系统上,您可能会达到32位进程大小的2Gb限制
如果您转移到64位系统但继续使用32位进程,则您的应用大小限制为4Gb
在具有64位处理的64位系统上,你可以达到8T左右
答案 1 :(得分:0)
不确切知道你的xslt对象是什么,但猜测它是一个XslCompiledTransform。你见过这个:MSDN Blog Article