Sun 的 Java 和 XML API:孰功孰过?

作者:Brett D. McLaughlin, Sr. ([email protected]), 作家兼编辑, O'Reilly Media, Inc.

Brett McLaughlin 从 Logo 时代就开始使用计算机。(还记得那个小三角吗?)近年来他已经成为 Java 技术和 XML 社区最知名的作家和程序员之一。他曾经在 Nextel Communications 实现过复杂的企业系统,在 Lutris Technologies 编写应用程序服务器,最近在 O'Reilly Media, Inc. 继续撰写和编辑这方面的图书。在他的新书 Head Rush Ajax 中,Brett 与畅销书作家 Eric 及 Beth Freeman 为 Ajax 带来了获奖的创新方法 Head First。他的上一本书 Java 1.5 Tiger: A Developer's Notebook 是第一本可获得的关于最新版本 Java 技术的书籍,而他的经典著作 Java and XML 仍然是在 Java 语言中使用 XML 技术的权威图书。



回顾古老的 JAXP

对于刚接触 Java 和 XML 的程序员(或者通过 Sun 和 J2SE 才接触到 XML 的程序员)来说,都有必要简要回顾一下早期的 JAXP。那时,JAXP 是 Java 和 XML 领域中排行第三的 API,风靡程度仅次于 SAX(Simple API for XML)和 DOM(Document Object Model)。JAXP 的目标非常简单:使 SAX 和 DOM 的使用更加简单,尤其是在供应商中立领域。

JAXP 是一个包装器 API

最初,JAXP 的目的仅仅是向 SAX 和 DOM 提供便利性和供应商中立性。根据这一点,JAXP 从未想过要替代 SAX 或 DOM;事实上,JAXP 在其早期版本中拥有一些方法,getXMLReader() 和 getDOMParser() 就是其中的两个。 显而易见,这些方法的存在表明 JAXP 的作者希望 开发人员使用 JAXP,然后操作底层的 SAX 和 DOM 实现类。

还有一点值得注意,虽然 JAXP 在这些年中不断地加入大量的功能,但是这两个方法从未修改过。有的人会说这不过是出于向后兼容性的考虑,不过这确实反应了 JAXP 从未打算将 SAX 或 DOM 取而代之。JAXP 只不过是将它们封装起来,这样开发人员就不必使用大量特定于供应商的代码来调用 SAX 或 DOM了。

JAXP 提供了供应商中立性

在早期的 Java 和 XML 编程中,存在大量 的 XML 解析器(最初的 Xerces 和 XML4J,Sun 公司的 Crimson,Oracle 公司的 XML 解析器,以及一些如今人们从未听过的解析器。)当我们编写一个与 XML 协作和交互的应用程序时,需要将 SAX 和 DOM API 连接到这些解析器实现,通常所使用的方法是将解析器类名告知 SAX 或 DOM,有点类似如下的方式:


Parser parser = new org.apache.xercers.parsers.SAXParser();


注意:我有意使用了较旧的 SAX Parser 接口;它是旧的 SAX 1 解析类,在 JAXP 成为问题的时期所有人都在使用它。

JAXP 引入了一个 javax.xml.parsers.SAXParserFactory 系统属性,它允许我们指定解析器工厂实现(工厂中提供了想要使用的解析器)。可以通过一个 System.setProperty() 系统属性指定工厂,也可以通过某些位置下的 jaxp.properties 文件来指定(本质上说,即应用程序类路径中的任何位置)。

无论采用何种方式指定这一属性 — 或者其对应的 DOM 属性 javax.xml.parsers.DocumentBuilderFactory — 都需要避免在解析代码中出现任何类名。这也是 JAXP 存在的首要原因:防止将此类信息直接放入代码。可以通过改变属性值来方便地修改各种属性,或者甚至建立多个 jaxp.properties 文件用于不同的解析器实现,并且在需要时对它们进行切换。



JAXP 现状

对于 Sun 公司推出 JAXP 的最初目的,您可以执有自己的看法,甚至可以否定其价值,但是此时这已经没有什么实际意义了。真正具有现实意义且值得讨论的是:JAXP 如今的角色是什么?以及人们正在如何使用它?如今,所有的 Java 发行版毫无例外的将 JAXP 囊入其中,显然 Java EE(J2SE and Java Platform, Enterprise Edition 5)、Java Platform 和 Java ME(Java ME)不包括在内,大约 95% 的 Java 和 XML 开发人员都在使用 JAXP。

JAXP 作为 SAX 和 DOM 的替代

随着时间的推移,JAXP 已不再封装 SAX 和 DOM,而是在逐步取代它们。现在我们需要记住,JAXP 本身并不是一个真的解析 API(在需要 SAX 或 DOM 解析器运作的情况下)。因此 JAXP 永远都无法从功能上取代 SAX 或 DOM;然而,它可以在实际应用中 取代它们,开发人员完全可以停止使用 SAX 包(org.xml.sax)或 DOM 包(org.w3c.dom)中的方法或类。

要验证这点,其中一个方法就是询问开发人员。因为 Sun 公司在促销(可以这样理解)自己的 API,而且 JAXP 与当前版本的 Java 技术 “绑” 在了一起,所以许多开发人员都是通过 JAXP 接触 XML 的。自然而然,他们开始学习使用 JAXP,甚至大多数已经牢固掌握 SAX 和 DOM 的开发人员也觉得 JAXP 更加好用。事实上,许多开发人员都完全没有意识到 SAX 和 DOM 是 JAXP 的基础!

所有这些使 SAX 和 DOM 在 JAXP 的光彩下逐渐离开人们的视线。对 ContentHandler 和 DOMImplementation 的谈论已成了昨日黄花,或者至少是相当高端的 Java 和 XML 程序员才会知道这些。这甚至与 5 年之前的相互抗衡的情形迥然不同,那时 JAXP 仍处于演化和起步阶段,除了 JAXP 之外开发人员通常至少会对 SAX 和 DOM 中的一种偏爱有加(许多情况下是两种)。

是添加了更多功能,还是维持原状?

然而,比起相互抗衡更加重要的一点是:甚至有人只 使用 JAXP — 而不是直接使用 SAX 和 DOM,或使用 JAXP 附带的那些 API — 这极大地限制了 XML 编程和解析功能。因为 JAXP 确实只是一个包装器 API(无论人们如何使用它),它无法使用 SAX 和 DOM 提供的任意选项。虽然我们可以在 JAXP 上设置解析器的特性和属性,并能处理内容和基本的错误处理,不过 SAX 尤其提供了大量的与语法相关的事件(DTD 和模式)和更高级的词法事件(如处理指令)。访问这些事件的惟一方式是直接操作 SAX XMLReader 接口。

请记住,我并不提倡将 JAXP 一棒子打死。我们可以将 JAXP 用作它的原始目的 — 访问解析器,而不必直接处理代码中的供应商解析器类 — 然后使用 JAXP 的 getXMLReader() 访问获取 SAX XMLReader 接口。这样,便可以轻松地直接操作 SAX — 但是所有这些需要我们首先了解如何操作 XMLReader 接口。

所有这些,我们可以看出 JAXP 表面是添加了一些功能 — 供应商中立性,一些便利性和帮助器方法 — 但是实际上可以移除这些内容。如果开发人员过分依赖于 JAXP(这已经成为了目前的问题),那么他们将非常容易忘记或甚至没有意识到 JAXP 并未公开 SAX 和 DOM 中的大量功能。因此,虽然 JAXP 本来是用于提供功能,但是它实际上减少了 Java 和 XML 程序员的工具。

开放源码问题?

我将这个问题留在最后讨论,其主要原因是它涉及到道德、合法性和各种会让大多数程序员觉得枯燥和无聊的内容。而且这似乎还不够,开放源码还将哲学牵扯进 来。总之,我想知道 Sun — 虽然一直将法律放在首位 — 是否没有违反法律精神(开放源码和社区方面)。当他们将 SAX API 作为基石,然后开始在 JAXP 中添加功能,我想知道他们为什么没有将这些功能融入到 SAX 中去?在 JAXP 中添加方法调用这些新功能(就是他们的大多数 API)也是完全可行的。但是这些功能就不能作为整体提交给 SAX API 吗?

事实上,如果 JAXP 的实用性是与 Sun 希望我们相信的那样(说实话,我没有必要讨论其实用性),那么为什么他们不将这些功能提供给我们。我们至少有时会倾向于单独使用 SAX,而不需要 JAXP。为了避免任何可能的混乱,我们仍然会选择使用 Java 技术,因此 Sun 公司通过 SAX(而不仅仅是 JAXP)将这些功能提供出来并不会失去任何业务(这甚至是一个笑话,就像 Sun 不再卖 Java 技术)。还有,这个问题虽然相当细微,但是却值得思考:如果 JAXP 提供了如此巨大的价值,难道其中一些价值就不能分给底层的 API 吗?JAXP 将仍然受益于在 SAX 和 DOM 之间轻易转换,不过对于 XML 社区来说将会是一个很大的欣喜。

结束语

我并不想在这里发表激昂的言论(不过我不会介意一些读者在 讨论论坛 上这样做),但是我仍然要质疑 JAXP — 和其他一些同一性质的 Sun API — 以及它从一个包装器 API 演化成为 “全能” 解析器 API。我认为 JAXP 埋没了 SAX 和 DOM 自身的价值,却没有换回任何有意义的价值。我很乐意 Sun 将 JAXP 作为针对供应商中立的一个封装层,并将解析方法和行为稳固地留在 XML 解析器和 API 供应商的领土中。


当然,Sun 公司并未向我致电征求我的意见,而且 Scott McNealy 肯定也从未听过我的名字,因此对于 Sun 的做法我们也无能为力。然而,设想如果您是一名 Java 和 XML 程序员,这至少会让您对 JAXP 的使用产生疑问 — 这就是他们的意图。如果程序员还要(重新)学习 SAX 和 DOM 的话,我们就会明智地开始使用 JAXP,事实上是为了更好地编写应用程序,因为我们能够在较低等级操作 XML 文档,而且能够更加游刃有余。然后,甚至连 Scott 都会注意到我们所编写的优秀应用程序,难道不是吗?因此您告诉我:这有什么意义吗?

你可能感兴趣的:(java)