首页
Preview

高效的Java XML解析

图片来自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 文件。

下一部分使用 XMLInputFactory 从流创建 StAX 读取器并开始读取文件。读取器提供一个基于推的 API,从流中拉出 XML 元素。第一个循环遍历文档,查找 <page> 开始元素,然后将控制权传递给 parsePage 函数来处理页面元素的处理。

parsePage 函数继续循环处理流中的事件。首先检查是否已到达页面元素的末尾并返回,因为我们已经读取了页面并完成了此函数的范围。

接下来搜索开始元素,并根据已达到的元素采取行动。这使我们能够快速遍历包含在 page 元素中的所有元素,提取所需的内容并忽略其余部分。可以轻松添加其他 caseswitch 语句中以处理 revision,调用其他函数以处理解析该元素的详细信息。

为什么这么简单?

编写 SAXParser 就像指导小丑如何杂耍一样。它很尴尬,并使本应该是相对简单的任务读取 XML 文件变得不必要地复杂。StAX 解析器将其反转过来,不是没有控制地被抛出元素,而是控制权留给调用者。与放弃控制并提供在事件发生时调用的函数不同,请求并根据需要处理事件,使控制权留给消费者。

Java 是一种伟大的语言,如果使用得当,但不幸的是,情况并非总是如此。SAXParser 就是这种情况之一,虽然它确实有用,但它的目的是很小众的。它不应该是高效 XML 解析的默认答案。为什么在标准库中存在更好的解决方案时,它仍然是默认答案,这让我感到困惑。

译自:https://medium.com/tech-travelstart/efficient-xml-parsing-with-java-df3169e1766b

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论