内存高效的XSLT处理器

时间:2008-10-23 17:46:15

标签: xslt

我需要一个工具来针对非常大的 XML文件执行XSLT。要清楚,我不需要设计,编辑或调试XSLT,只需执行它们。我正在使用的变换已经很好地优化了,但是大文件导致我尝试过的工具(Saxon v9.1)内存不足。

10 个答案:

答案 0 :(得分:5)

我找到了一个很好的解决方案:Apache的Xalan C++。它提供了pluggable memory manager,允许我根据输入和变换调整分配。

在多种情况下,与我尝试的其他内存相比,它消耗的内存减少了约60%(我正在查看私有字节)。

答案 1 :(得分:3)

您可能希望查看STX以进行基于流的XSLT转换。或者,我相信StAX可以integrate with XSLT nicely通过Transformer界面。

答案 2 :(得分:2)

这听起来像是你的排序 - 但通常,另一种可能的方法是首先拆分数据。显然,这只适用于一些转换(即可以从整体上单独处理不同的数据块) - 但是你可以使用一个简单的解析器(而不是DOM)来分割成可管理的部分,然后处理每个块分开并重新组装。

因为我是.NET的人,所以像XmlReader这样的东西可以在没有DOM的情况下进行分块;我确信每种语言都有等价物。

再次 - 只是为了完整。

[编辑问题] 我不知道任何具体的名字;也许Divide and Conquer。 举个例子;如果您的数据实际上是类似对象的平面列表,那么您可以简单地拆分第一级子级 - 即,而不是有2M行,将其拆分为10批200K行或100批20K行。我之前已经多次使用批量数据(例如,上传数据块[全部有效]并在服务器上重新组装,以便每个单独的上传都足够小,以便健壮)。

答案 3 :(得分:2)

对于它的价值,我怀疑对于Java来说,如果你需要使用XSLT,那么Saxon就像它一样好。它对于较大的文档非常有效(包括cpu和内存),但XSLT本身实际上强制创建和保留完整的内存中的内容树,除了有限的情况。 Saxon-SA(收费版)据说可以扩展以利用这种“流媒体”案例,因此可能值得一试。

但是拆分内容的建议是最好的:如果你正在处理独立记录,只需使用其他技术分割输入(比如,使用Stax!:-))

答案 4 :(得分:1)

我发现使用早期版本的MSXML运行XSLT而构建的自定义工具使其非常快,但也消耗了大量的内存,如果太大则无法实际完成。您也失去了一些高级XSLT功能,因为早期版本的MSXML不支持完整的xpath内容。

如果你的其他选择花了太长时间,那值得一试。

答案 5 :(得分:1)

这是一个有趣的问题。 XSLT可能会针对空间进行优化,但我希望除了最晦涩的实现之外的所有实现都可以通过将源文档解析为DOM来实现,DOM必然会在内存中使用文档大小的低倍。

除非样式表专门用于支持单遍转换,否则合理的时间性能可能需要将源文档解析为基于磁盘的分层数据库。

但我没有答案。

答案 6 :(得分:1)

Saxon 9.2似乎可以为您的问题提供答案。如果可以在不使用谓词的情况下转换文档(不引用当前节点的任何兄弟),则可以使用Streaming XSLT。 见this link

我自己没试过,我只是在读它。但我希望它有效。

答案 7 :(得分:0)

您使用的是Saxon的Java版本还是.Net端口?如果内存不足(使用-Xms命令行参数),可以为运行Saxon的Java VM分配更多内存。

我还发现,Saxon的.Net版本比Java版本更容易耗尽内存。

答案 8 :(得分:0)

对于.NET,您可以使用Microsoft知识库中的解决方案建议: http://support.microsoft.com/kb/307494

XPathDocument srcDoc = new XPathDocument(srcFile);
XslCompiledTransform myXslTransform = new XslCompiledTransform();
myXslTransform.Load(xslFile);
using (XmlWriter destDoc = XmlWriter.Create(destFile))
{
    myXslTransform.Transform(srcDoc, destDoc);
}

答案 9 :(得分:-2)

查看Xselerator