DOM与SAX XML解析大文件

时间:2013-06-26 02:21:35

标签: java javascript xml parsing dom

背景:

我有一个大型OWL(Web Ontology Language)文件(大约125MB或 150万行)我想要解析为一组制表符分隔值。我一直在研究SAX和DOM XML解析器,并发现了以下内容:

  • SAX允许逐个节点读取文档,因此整个文档不在内存中。
  • DOM允许将整个文档一次性放入内存,但是有很多开销。

SAX与大文件的DOM:

据我所知,

  • 如果我使用 SAX ,我将不得不逐节点地迭代150万行代码。
  • 如果我使用 DOM ,我会有很大的开销,但结果会很快返回。

问题:

我需要能够在相同长度的类似文件上多次使用此解析器。

因此,我应该使用哪种解析器?

奖励积分:有没有人知道JavaScript的任何好的解析器。我发现很多都是为Java制作的,但我对JavaScript更加满意。

3 个答案:

答案 0 :(得分:5)

符合StAX

就像SAX一样,StAX遵循 Streaming 编程模型来解析XML。但是,它是DOM的双向读/写支持,易用性和SAX的CPU和内存效率之间的交叉。

SAX是只读的,并且推送解析强制您在那里处理事件和错误,然后在解析输入时。另一方面,StAX是一个拉解析器,它允许客户端在需要时调用解析器上的方法。这也意味着应用程序可以同时读取多个XML文件。

JAXP API比较

╔══════════════════════════════════════╦═════════════════════════╦═════════════════════════╦═══════════════════════╦═══════════════════════════╗
║          JAXP API Property           ║          StAX           ║           SAX           ║          DOM          ║           TrAX            ║
╠══════════════════════════════════════╬═════════════════════════╬═════════════════════════╬═══════════════════════╬═══════════════════════════╣
║ API Style                            ║ Pull events; streaming  ║ Push events; streaming  ║ In memory tree based  ║ XSLT Rule based templates ║
║ Ease of Use                          ║ High                    ║ Medium                  ║ High                  ║ Medium                    ║
║ XPath Capability                     ║ No                      ║ No                      ║ Yes                   ║ Yes                       ║
║ CPU and Memory Utilization           ║ Good                    ║ Good                    ║ Depends               ║ Depends                   ║
║ Forward Only                         ║ Yes                     ║ Yes                     ║ No                    ║ No                        ║
║ Reading                              ║ Yes                     ║ Yes                     ║ Yes                   ║ Yes                       ║
║ Writing                              ║ Yes                     ║ No                      ║ Yes                   ║ Yes                       ║
║ Create, Read, Update, Delete (CRUD)  ║ No                      ║ No                      ║ Yes                   ║ No                        ║
╚══════════════════════════════════════╩═════════════════════════╩═════════════════════════╩═══════════════════════╩═══════════════════════════╝

参考:
Does StAX Belong in Your XML Toolbox?

  

StAX 是一种“拉”型API。如上所述,有Cursor和Event Iterator API。 API有读写两面。它比SAX更适合开发人员。与SAX一样,StAX不需要将整个文档保存在内存中。但是,与SAX不同,不需要读取整个文档。部分可以跳过。这可能导致性能甚至比SAX提高。

答案 1 :(得分:2)

你最想要SAX。

DOM不一定更快;它可能会慢一点,如果它可以工作,并且,正如你所说,你需要在记忆中保持很多,可能是不必要的。

答案 2 :(得分:2)

OWL XML语法相当平坦,但包含许多交叉引用。

如果您需要解决交叉引用,那么流式方法(如SAX或StAX)是不可行的;您需要在内存中构建一个包含整个树的数据结构。如果你打算使用内存中的树,不要使用DOM,使用一个更现代的模型,如JDOM2或XOM - 它们更有效,更实用。

如果流式方法是可行的 - 也就是说,如果输入和输出之间存在非常直接的对应关系,那么StAX比SAX更容易使用,因为您可以将当前状态保存在Java堆栈中的变量中,而不是需要复杂的数据结构来维持调用之间的状态。

然而,还有另一种选择;你可以在流式XSLT 3.0中编写全部内容。说实话,这是前沿,你的学习时间可能会更大;而且它不是开源的;但你最终可能会得到10行代码而不是300行的解决方案。

我还没有尝试过其他流技术,比如XStream。