我有一个非常大的XML文件,我需要将其转换为另一个XML文件,我想用XSLT来做这件事。我对内存优化更感兴趣,而不是优化速度(尽管速度也会很好!)。
您为此任务推荐哪种基于Java的XSLT处理器?
你会推荐其他任何方式(非XSLT?,非Java?),如果是这样,为什么?
问题中的XML文件非常大,但不是很深 - 有数百万行(元素),但只有大约3个级别。
答案 0 :(得分:31)
目前只有三个XSLT 2.0处理器已知,而且Saxon 9.x可能是速度和内存效率最高的(至少根据我的经验)利用。 Saxon-SA (撒克逊的架构感知版本,不是免费的B(基本)版本)具有流式处理的特殊扩展。
来自各种现有 XSLT 1.0 处理器,.NET XslCompiledTransform (基于C#,而不是Java! )似乎是冠军。
在基于Java的XSLT 1.0处理器世界中 Saxon 6.x 再次相当不错。
<强>更新强>:
现在,从最初回答此问题之日起超过3年,没有任何证据表明所提到的XSLT处理器之间的效率差异发生了变化。
至于流媒体:
以下是Saxon的信息性消息,显示有关转型的详细信息:
Saxon 9.1.0.7J from Saxonica Java version 1.6.0_17 Stylesheet compilation time: 190 milliseconds Processing file:/C:\temp\delete\MRowst.xml Building tree for file:/C:\temp\delete\MRowst.xml using class net.sf.saxon.tinytree.TinyBuilder Tree built in 1053 milliseconds Tree size: 3075004 nodes, 1800000 characters, 0 attributes Loading net.sf.saxon.event.MessageEmitter Execution time: 1448 milliseconds Memory used: 506661648 NamePool contents: 14 entries in 14 chains. 6 prefixes, 6 URIs
以下摘自文档:
在Saxon中基本上有两种流媒体方式:
Burst-mode streaming:用这种方法,转换一个 大文件被分解为一系列小变换 文件的各个部分。转动从输入中读取每个部分 进入内存中的一个小树,转换并写入输出 文件。
这种方法适用于结构相当扁平的文件, 例如,一个包含数百万条日志记录的日志文件 每个日志记录的处理与那些记录的处理无关 之前。
此技术的一种变体使用新的XSLT 3.0 xsl:iterate 迭代记录的指令,代替xsl:for-each。 这允许工作数据作为记录保持 已处理:例如,这可以输出总数或 在运行结束时的平均值,或者进行一次处理 记录取决于文件中的内容。 xsl:迭代 指令还允许提前退出循环,这使得它成为可能 转换可以从一开始就处理数据 没有实际读取整个文件的大文件。
XSLT和XQuery都提供了突发模式流,但有 在XQuery中与xsl:iterate构造不相同。
流模板:这种方法遵循传统的XSLT 执行输入XML的递归下降的处理模式 通过将模板规则匹配到每个级别的节点,但是 一次只做一个元素,而不在内存中构建树。
每个模板都属于一种模式(可能是默认的,未命名的模式), 和流是可以使用指定的模式的属性 新的xsl:mode声明。如果声明模式 流式传输,那么该模式中的每个模板规则都必须服从 流媒体处理规则。
流式处理允许的规则是相当的 复杂,但基本原则是模板规则 给定节点只能读取该节点的后代一次 订购。目前的限制还有其他规则 Saxon实现:例如,尽管使用分组 在理论上是一致的 使用流式实现,目前尚未实现 撒克逊。
XSLT 3.0会有标准streaming feature 。但是,W3C文档仍处于“工作草案”状态,并且流式规范可能会在后续草稿版本中发生变化。因此,不存在当前草案(流媒体)规范的实现。
警告:并非所有转换都可以在流模式下执行 - 无论XSLT处理器如何。对于大型文档,无法在流模式(具有有限数量的RAM)中执行的转换的一个示例是对其元素进行排序(例如,通过共同属性)。
答案 1 :(得分:8)
您可以考虑STX,其Java实现为Joost。由于它类似于XSLT,但作为流处理器,它能够使用非常少的RAM处理大量文件。
Joost可以用作标准的javax.xml.transform.TransformerFactory
答案 2 :(得分:3)
请参阅Saxon对流模式的支持。 http://www.saxonica.com/html/documentation/sourcedocs/streaming/
如果此流模式不适合您,您可以尝试使用Saxon的tiny tree mode,这是针对较小的内存使用量进行了优化的。 (无论如何都是默认的)