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

时间:2010-06-23 11:12:36

标签: c# xml xslt

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

我的代码看起来像;

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并进行转换。

3 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:0)

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

   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);

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