图片来自Unsplash,摄影师:Farzad Nazifi

本文最初发布于martinrichards.me

解析 XML 的方法不止一种?

解析 XML 文档有两种方法:读取整个文档并构建表示文档的完整 DOM 对象,或者作为流读取文档,从流中提取所需内容。DOM 方法对于像配置文件这样的小型文档很好,但在处理任何真实大小的文档时完全失效。

在 Java 中进行流解析时,SAX 解析器似乎是最常见的选择。关于在 Java 中解析大型 XML 文件的大多数 Stack Overflow 回答 和 教程 都指向 SAX 解析器。SAX 解析器唯一的问题在于其事件驱动的 API 很难使用。定义事件侦听器(处理程序)并等待其被调用会移除你对流的控制。当我处理流时,我喜欢控制程序的执行,并且一直更喜欢基于推的 API。

幸运的是,像编程中的大多数事情一样,我不是第一个经历这些痛点的人。创建了 StAX API,通过为 XML 流提供基于推的 API 来解决这个痛点。

这种方法的优点最好由 JavaDocs 描述:

与推处理相比,拉处理在处理 XML 流时提供了多个优点:

通过拉处理,客户端控制应用程序线程,并且可以在需要时调用解析器上的方法。相比之下,使用推处理,解析器控制应用程序线程,客户端只能接受来自解析器的调用。

相比于推库,拉库可以更小,并且与那些库交互的客户端代码更简单,即使对于更复杂的文档也是如此。

拉客户端可以使用单个线程读取多个文档。

StAX 拉解析器可以过滤 XML 文档,使客户端不需要的元素被忽略,并且它可以支持非 XML 数据的 XML 视图。

展示这个魔法!

让我们以维基百科数据集为例,以下是数据的样本:

以下是提取每个页面的名称和 ID 的代码:

简单易懂...

等等!发生了什么?

你可以在这里看到完整的项目,第一部分从资源文件夹中提取 XML 文件。

XMLInputFactoryStAX<page>parsePage
parsePage
pagecaseswitchrevision
为什么这么简单?
SAXParserStAX
SAXParser