我使用以下方法使用 C# 中的 XSLT 样式表将 XML 数据转换为 HTML。但是,在处理大型 XML 数据时,我遇到了
OutOfMemoryException
。如何优化此方法以处理大型 XML 和 XSLT 数据而不耗尽内存?
private static string TransformXMLToHTML(string xsltString, string xmlData) {
XslCompiledTransform transform = new XslCompiledTransform();
using (XmlReader reader = XmlReader.Create(new StringReader(xsltString)))
{
transform.Load(reader);
}
UTF8StringWriter results = new UTF8StringWriter();
using (XmlReader reader = XmlReader.Create(new StringReader(xmlData)))
{
transform.Transform(reader, null, results);
}
return results.ToString(); }
UTF8StringWriter:
public class UTF8StringWriter : StringWriter
{
public UTF8StringWriter() { }
public UTF8StringWriter(IFormatProvider formatProvider) : base(formatProvider) { }
public UTF8StringWriter(StringBuilder sb) : base(sb) { }
public UTF8StringWriter(StringBuilder sb, IFormatProvider formatProvider) : base(sb, formatProvider) { }
public override Encoding Encoding
{
get
{
return Encoding.UTF8;
}
}
}
注意:我引用了其他类似的问题,很少建议使用文件流,但我不能在这里使用它,因为它将引入处理文件相关的操作,我们不能将其应用于我们的整个代码库
编辑:
完全例外:
Exception: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at <xsl:template match="/">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer)
at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XsltArgumentList arguments, TextWriter results)
at CreateMailActivityImpl.TransformXMLToHTML(String xsltString, String xmlData)
您最好的选择是使用流,这样您就不会一次又一次地创建不必要的字符串。例如,您可以使用文件中的
FileStream
,或 HTTP 或 TCP 服务器中的 NetworkStream
。也可以预先调整大小 MemoryStream
,这样您就可以防止不必要的调整大小。
private static void TransformXMLToHTML(Stream xslt, Stream xmlData, Stream output)
{
var transform = new XslCompiledTransform();
using (var reader = XmlReader.Create(xsltString))
{
transform.Load(reader);
}
using var reader = XmlReader.Create(xmlData);
using var writer = XmlWriter.Create(output);
transform.Transform(reader, null, results);
}