我有一个非常大的XML文件,需要将其转换为另一个XML文件,并且我想使用XSLT做到这一点。我对内存优化而不是速度优化更感兴趣(尽管速度也不错!)。
您将推荐使用哪个基于Java的XSLT处理器?
您是否会推荐其他方法(非XSLT,非Java?),如果可以,为什么?
问题中的XML文件很大,但不是很深-有数百万行(元素),但只有大约3个级别。
目前,只有三个 已知的XSLT 2.0处理器,从速度和内存利用率两方面来看,
Saxon 9.x
可能是最高效的(至少根据我的经验)。 Saxon-
SA
( Saxon的模式识别
版本,由于B(基本)版本不是免费的)具有用于流处理的特殊扩展。
从各种现有的 XSLT 1.0 处理器中,.NET
XslCompiledTransform (基于C#,而不是Java!)似乎是冠军。
在XSLT 1.0处理器的基于Java的世界中, 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
以下是文档摘录 :
在撒克逊人流中基本上有两种方法:
突发模式流传输:通过这种方法,将大文件的转换分解为文件小片段的转换序列。依次从输入中读取每个片段,将其变成内存中的一棵小树,进行转换,然后写入输出文件。
此方法适用于结构相当平坦的文件,例如包含数百万条日志记录的日志文件,其中每个日志记录的处理均独立于之前的记录。
此技术的一种变体使用新的XSLT 3.0 xsl:iterate指令代替xsl:for-
each遍历记录。这样可以在处理记录时维护工作数据:例如,可以在运行结束时输出总计或平均值,或者根据文件中记录的内容来处理一条记录。
。xsl:iterate指令还允许提早退出循环,这使得转换可以从大文件的开头处理数据,而无需实际读取整个文件。XSLT和XQuery均提供突发模式流传输,但是XQuery中没有与xsl:iterate构造等效的流。
流模板:这种方法遵循传统的XSLT处理模式,该模式通过将模板规则与每个级别的节点匹配来执行输入XML层次结构的递归下降,但是一次这样做一个元素,而无需在内存中构建树。
每个模板都属于一个模式(也许是默认的未命名模式),流式传输是该模式的属性,可以使用新的xsl:mode声明来指定。如果该模式被声明为可流式处理,则该模式下的每个模板规则都必须遵守可流式处理规则。
流处理中允许的规则非常复杂,但是基本原理是给定节点的模板规则只能按顺序读取该节点的后代一次。当前Saxon实现中的限制还带来了其他规则:例如,尽管分组使用从理论上讲与流式实现是一致的,但当前在Saxon中尚未实现。
XSLT 3.0 将具有标准的流功能。但是,W3C文档仍处于“工作草案”状态,并且流式传输规范可能会在后续的草案版本中更改。因此,不存在当前草案(流)规范的实现。
警告 :并非所有转换都可以在流模式下执行-与XSLT处理器无关。对于大型文档,无法在流模式(RAM数量有限)中无法执行的转换示例之一是对它们的元素进行排序(例如,使用公共属性)。
本文向大家介绍Kafka的流处理是什么意思?相关面试题,主要包含被问及Kafka的流处理是什么意思?时的应答技巧和注意事项,需要的朋友参考一下 答:连续、实时、并发和以逐记录方式处理数据的类型,我们称之为Kafka流处理。
问题内容: 什么是最有效的Java Collections库? 几年前,我做了很多Java的工作,给人留下的印象是那个宝库是最好(最有效)的Java Collections实现。但是,当我阅读“最有用的免费Java库? ”这个问题的答案时,我注意到几乎没有提到trove。那么,哪个Java Collections库现在最好? 更新:为澄清起见,我主要想知道当我必须在哈希表等中存储数百万个条目时使用
问题内容: 什么是最好的Java图像处理库/方法?[关闭]我同时使用JAI媒体API和ImageMagick吗? ImageMagick存在一些可伸缩性问题,基于JNI的JMagick也没有吸引力。与ImageMagick相比,JAI执行大小调整操作时的质量结果较差。 有谁知道过任何出色的开源或商业工具,它们都是本机Java并可以提供高质量的结果? 问题答案: 我知道这个问题已经很老了,但是随着新
问题内容: 我有一个方法可以执行一些超时任务。我使用ExecutorServer.submit()获取Future对象,然后使用超时调用future.get()。这工作正常,但是我的问题是处理可能由我的任务引发的检查异常的最佳方法。以下代码可以正常工作,并保留检查的异常,但是如果方法签名中的检查的异常列表发生更改,则显得非常笨拙且容易中断。 对于如何解决这个问题,有任何的建议吗?我需要以Java
问题内容: 引用,Sun的官方Java教程 仅当显式请求注释处理时,才接受类名“ HelloWorldApp” 这是什么意思?以及如何应用呢? 问题答案: “注释处理”是Java编译器编译过程的一个钩子,用于分析用户定义的注释的源代码并进行处理(通过产生编译器错误,编译器警告,发出源代码,字节代码…)。 API参考:http://java.sun.com/javase/6/docs/api/jav
在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据。 例如,假设操作系统的堆栈已收到三个数据包: 由于基于流的协议的这种通用属性,在应用程序中以下面的碎片形式(只