我有一些非常大的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并进行转换。
答案 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);
可能需要一段时间但似乎确实完成了工作。