使用C#对大型XML文件进行XSLT转换

我有一些非常大的XML文件(800 MB到1.5 GB)。 我需要在那上面应用XSLT。 我能够读取XMLTextReader。 当我应用XSLT转换时,获取SystemOutOfMemory Exception。

我的代码看起来像;

static void Main(string[] args) { XDocument newTree = new XDocument(); XmlTextReader oReader = new XmlTextReader(@"C:\Projects\myxml.xml"); using (XmlWriter writer = newTree.CreateWriter()) { XslCompiledTransform oTransform = new XslCompiledTransform(); oTransform.Load(@"C:\Projects\myXSLT.xsl"); oTransform.Transform(oReader, writer); } Console.WriteLine(newTree); } 

提前致谢。 这是非常紧急的。 如果我没有得到任何解决方案,我需要将XML拆分为更小的XML并进行转换。

XSLT使用XPath,这要求将整个XML文档保存在内存中。 因此,根据定义,存储器不足的问题

有一些simle规则来估计需要多少内存,其中一个说5 * text-size

因此,对于“典型的1.5GB XML文件”,8GB RAM可能就足够了。

将文档拆分为较小的部分或等待XSLT 2.1的实现, XSLT 2.1定义了特殊的流指令。 与此同时,人们可能会使用Saxon的最新(商业)版本,该版本实现了流媒体扩展和64GB文档的成功处理。

我们正面临着类似的问题。 我们提出的解决方案是在这种情况下不使用xslt,而是在对数据进行stteaming时使用Linq进行Xml转换。 您可以利用c#yield关键字迭代xml流并以这种方式逐步处理文件。 请参阅使用linq到xml的流式传输

xslt的本质要求将xml加载到内存中。 需要发生的是你需要将大文件分解为更多可管理的部分。 如果您使用xml流技术,您可以将文档分解为子元素,然后您可以单独应用xslt。 您可能必须重写xslt以适应此行为。

除此之外,唯一的另一种选择是在其上投入更多硬件,但这甚至可能需要根据RAM限制进行操作系统升级……

不知道它是否有用,但这里有一些我用来转换大文件的代码:

  XPathDocument myXPathDoc = new XPathDocument("xmfile.xml"); XslCompiledTransform myXslTrans = new XslCompiledTransform() ; XsltSettings st = new XsltSettings(true, true); myXslTrans.Load("StyleSheet.xslt", st, null); StreamWriter s =new StreamWriter("output-fie.xslt"); XsltArgumentList ln = new XsltArgumentList(); // some xslt argument processing stuff myXslTrans.Transform(myXPathDoc, ln, s); 

它可能需要一段时间,但似乎确实完成了工作。