什么是最高效的基于Java的流式XSLT处理器?

时间:2009-01-20 11:26:46

标签: java xslt processor

我有一个非常大的XML文件,我需要将其转换为另一个XML文件,我想用XSLT来做这件事。我对内存优化更感兴趣,而不是优化速度(尽管速度也会很好!)。

您为此任务推荐哪种基于Java的XSLT处理器?

你会推荐其他任何方式(非XSLT?,非Java?),如果是这样,为什么?

问题中的XML文件非常大,但不是很深 - 有数百万行(元素),但只有大约3个级别。

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处理器之间的效率差异发生了变化。

至于流媒体

  1. 即使没有任何流式传输,也可以处理具有“数百万个节点”的XML文档。我进行了一项实验,其中Saxom 9.1.07处理了一个XML文档,该文档包含大约一百万个具有整数值的3级元素。转换只是计算它们的总和。在我的计算机上进行转换的总时间不到1.5秒。用过的内存是500MB - 这是个人电脑10年前就可以拥有的东西,
  2. 以下是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
    
    1. Saxon 9.4 saxon:stream() extension function ,可用于处理大量XML文档。
    2. 以下摘自文档

        

      在Saxon中基本上有两种流媒体方式:

           

      Burst-mode streaming:用这种方法,转换一个   大文件被分解为一系列小变换   文件的各个部分。转动从输入中读取每个部分   进入内存中的一个小树,转换并写入输出   文件。

           

      这种方法适用于结构相当扁平的文件,   例如,一个包含数百万条日志记录的日志文件   每个日志记录的处理与那些记录的处理无关   之前。

           

      此技术的一种变体使用新的XSLT 3.0 xsl:iterate   迭代记录的指令,代替xsl:for-each。   这允许工作数据作为记录保持   已处理:例如,这可以输出总数或   在运行结束时的平均值,或者进行一次处理   记录取决于文件中的内容。 xsl:迭代   指令还允许提前退出循环,这使得它成为可能   转换可以从一开始就处理数据   没有实际读取整个文件的大文件。

           

      XSLT和XQuery都提供了突发模式流,但有   在XQuery中与xsl:iterate构造不相同。

           

      流模板:这种方法遵循传统的XSLT   执行输入XML的递归下降的处理模式   通过将模板规则匹配到每个级别的节点,但是   一次只做一个元素,而不在内存中构建树。

           

      每个模板都属于一种模式(可能是默认的,未命名的模式),   和流是可以使用指定的模式的属性   新的xsl:mode声明。如果声明模式   流式传输,那么该模式中的每个模板规则都必须服从   流媒体处理规则。

           

      流式处理允许的规则是相当的   复杂,但基本原则是模板规则   给定节点只能读取该节点的后代一次   订购。目前的限制还有其他规则   Saxon实现:例如,尽管使用分组    在理论上是一致的   使用流式实现,目前尚未实现   撒克逊。

      1. XSLT 3.0会有标准streaming feature 。但是,W3C文档仍处于“工作草案”状态,并且流式规范可能会在后续草稿版本中发生变化。因此,不存在当前草案(流媒体)规范的实现。

      2. 警告:并非所有转换都可以在流模式下执行 - 无论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,这是针对较小的内存使用量进行了优化的。 (无论如何都是默认的)