.NET XSLT转换,这真的是流式传输吗?

Sta*_* R. 3 .net c# xslt stream

我有一个XML,我需要从中删除空元素.我试图避免使用DOM,并尝试将其作为流.我有这个代码,但我不完全确定这是多么正确和优化.

StringBuilder xslt = new StringBuilder();
xslt.Append(@"<?xml version=""1.0"" encoding=""UTF-8""?>");
xslt.Append(@"<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">");
xslt.Append(@"<xsl:output method=""xml"" version=""1.0"" encoding=""UTF-8"" indent=""yes""/>");
xslt.Append(@"<xsl:template match=""*"">");
xslt.Append(@"<xsl:if test=""count(@*) > 0 or count(node()) > 0"">");
xslt.Append(@"<xsl:copy>");
xslt.Append(@"<xsl:apply-templates select=""@* | node()""/>");
xslt.Append(@"</xsl:copy>");
xslt.Append(@"</xsl:if>");
xslt.Append(@"</xsl:template>");
xslt.Append(@"<xsl:template match=""@* | text()"">");
xslt.Append(@"<xsl:copy/>");
xslt.Append(@"</xsl:template>");
xslt.Append(@"</xsl:stylesheet>");

StringBuilder resultString = new StringBuilder();
XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(resultString));
XmlTextReader xmlReader = new XmlTextReader(new StringReader(xmlString));

System.Xml.Xsl.XslCompiledTransform xslTransform = new System.Xml.Xsl.XslCompiledTransform();
xslTransform.Load(new XmlTextReader(new StringReader(xslt.ToString())));
xslTransform.Transform(xmlReader, xmlWriter);
xmlReader.Close();

xmlWriter.Flush();
xmlWriter.Close();
Run Code Online (Sandbox Code Playgroud)

这是一个很好的方法吗?

cka*_*ras 6

是的,您正在使用流,但是您正在失去流的一个好处:不会立即将整个XML输入和输出加载到内存中.

这对于非常小的XML文档来说非常好,但它可以导致大型文档的内存使用率非常高.

解决方案是避免使用StringReader/StringWriter,而是使用适当的流实现,具体取决于应从何处读取和发送XML.例如:

  • 如果要转换为XML文件或从XML文件转换,请使用FileStreams.
  • 如果要通过套接字/ HTTP连接发送,请使用连接对象提供的流.

此外,从嵌入式字符串加载XSLT通常不是一个好主意(更难维护),但我不认为它会导致性能问题(除非XSLT真的很大).为了更好的可维护性,我建议将XSLT存储在另一个文件中.该文件既可以从文件系统加载(使用FileStream),也可以作为"嵌入式资源"存储在已编译的DLL文件中并加载assembly.GetManifestResourceStream().