3

背景:

我有一个大型 OWL(Web 本体语言)文件(大约 125MB 或150 万行长),我想将其解析为一组制表符分隔的值。我一直在研究 SAX 和 DOM XML 解析器,发现以下内容:

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

大文件的 SAX 与 DOM:

据我了解,

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

问题:

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

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

加分项:有谁知道任何好的 JavaScript 解析器。我意识到很多都是为 Java 制作的,但我更喜欢 JavaScript。

4

3 回答 3

5

认识 StAX

就像SAXStAX遵循用于解析 XML的流式编程模型。DOM但是,它是双向读/写支持、易用性以及SAXCPU 和内存效率之间的交叉。

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

JAXP API 比较

╔══════════════════════════════════════╦══════════ ═══════════════╦═════════════════════════╦════════ ═══════════════╦═════════════════════════╕
║ JAXP API 属性 ║ StAX ║ SAX ║ DOM ║ TrAX ║
╠══════════════════════════════════════╬══════════ ═══════════════╬═════════════════════════╬════════ ═══════════════╬══════════════════════════
║ API 风格 ║ 拉取事件;流式传输 ║ 推送事件;流式传输 ║ 基于内存树 ║ XSLT 基于规则的模板 ║
║ 易用性 ║ 高 ║ 中 ║ 高 ║ 中 ║
║ XPath 能力 ║ 否 ║ 否 ║ 是 ║ 是 ║
║ CPU 和内存利用率 ║ 好 ║ 好 ║ 取决于 ║ 取决于 ║
║ 仅转发 ║ 是 ║ 是 ║ 否 ║ 否 ║
║ 阅读 ║ 是 ║ 是 ║ 是 ║ 是 ║
║写作║是║否║是║是║
║ 创建、读取、更新、删除 (CRUD) ║ 否 ║ 否 ║ 是 ║ 否 ║
╚══════════════════════════════════════╩══════════ ═══════════════╩═════════════════════════╩════════ ═══════════════╩═════════════════════════╕

参考:
StAX 是否属于您的 XML 工具箱?

StAX是一种“拉”类型的 API。如前所述,有游标和事件迭代器 API。API 有读写两面。它比 SAX 对开发人员更友好。StAX 与 SAX 一样,不需要将整个文档保存在内存中。但是,与 SAX 不同的是,不需要读取整个文档。部分可以跳过。这可能会导致甚至比 SAX 更好的性能。

于 2013-06-26T03:20:13.873 回答
2

您很可能需要 SAX。

DOM 不一定更快;如果它完全有效,它可能会让我更慢,而且,正如你所说,你需要在内存中保存很多,可能是不必要的。

于 2013-06-26T02:25:50.933 回答
2

OWL XML 语法相当扁平,但包含大量交叉引用。

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

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

但是,还有另一种选择;您可以在流式 XSLT 3.0 中编写整个内容。老实说,这是最前沿的,你的学习时间可能会更长;而且它不是开源的;但你很可能最终会用 10 行代码而不是 300 行代码来解决问题。

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

于 2013-06-26T08:09:59.210 回答