XML 是关于灵活性的
不需要详细研究 XML 起源的长期历史原因,在开始这个讨论话题之前我想再次重申 XML 最初确实是关于灵活性的。XML 提供了一种供应商中立的格式来表示数据。根据对 XML 规范内容和要求的一致理解,应用程序可以轻易生成这种格式,并且其它应用程序也可以方便地使用这种格式。以更通俗的语言来说,如果您告诉我您使用的是 XML,然后再告诉我您所使用的元素和属性,我很快就能写出能读取和使用 XML 的代码来。反过来也一样,如果我向您提供了我的约束模型 (constraint model)(通常为 DTD 或者 XML Schema 格式),您就能够很快地操作我的数据。
最初的 API 可以维持这种灵活性
不足为奇,当 XML API 刚开始出现的时候,它们都非常的简单。最初版本的 Simple API for XML(SAX)和文档对象模型(Document Object Model,DOM)只具备非常基础的操作。您可以从某个元素中获得数据,操作其子元素,找出某个属性的值等,全部都是这方面的操作。除了处理 XML 的词汇结构之外,这些 API 并未提供大量的特性。
在 XML 发展的初期,这被认为是件好事。这非常像过去程序员对 C 语言和汇编语言做的一样,以对计算机中底层的比特和字节维持最大控制,SAX 特别适合于处理原始的 XML 文档 — 具有基本格式的数据 — 并允许您的程序完成需要的操作,而不需要花费业余时间研究这些 XML API。
然后出现了包装 API
首次告别低级控制 — 从理论上说实现了开发人员友好的 API — 的是 JAXP,Sun 公司用于处理 XML 的 Java API。最初,JAXP 的目标是从 SAX 和 DOM 代码中移除一些特定于供应商的信息(涉及到所使用的 XML 解析器)。
然而,为了努力提供一些便利,JAXP 提供了几个辅助方法(helper method),从本质上说就是把 SAX 和 DOM 中已有的功能封装起来。因为 Sun 公司在 Java 市场上影响如此巨大,所以开发人员很快就开始使用这些辅助方法了,并且很少再直接操作 SAX 和 DOM 了 。
程序员仍然需要了解 SAX 的基本原理(如什么是 ContentHandler 以及如何实现回调方法),但是 JAXP 抽象出了很多这样的细节。事实上,要执行特定的动作,如设置一些 SAX 中不常见的词汇句柄,我们不得不 绕开 JAXP 而直接操作 SAX。
如今又出现了数据绑定,JDOM 和大量的 API
差不多在十年之后(取决于您所使用的日期),又出现了许多其它种类的 API。除了 SAX、DOM 和 JAXP 之外,我们还可以使用 JDOM、XOM、dom4j、StAX 和一些其它的变体非常直接地操作 XML。一些数据绑定 API,如 Zeus、Castor 和 JAXB 能允许我们在对 XML 没有多少了解的情况下处理 XML,而不用操作 XML 文档表示为逻辑数据而不是字符串或其他数据的数据。并且 Eclipse 之类的框架将完成所有这些操作,而您只需指定、单击和修改 XML 就可以了。从字面上看,有数百种方案可供选择(使用 XSLT 后我甚至不需关心 XML 的转换了)。
我们仍然具备灵活性吗?
掌握了所有可用于操作 XML 的 API 之后,Java 和 XML 程序员似乎具备了前所未有的高度灵活性; 那么选择就意味着灵活性吗?我们稍微质疑一下这一断言,看它是否真的站得住脚。
解析程序中的灵活性
毫无疑问,我们能够使用所想要的任何 XML 解析器,任何版本和风格的解析器都可以,只要我们具有某些类文件 — 大多数情况下,这些文件都捆绑在所选的 API 中。因此要方便地从 XML4J 转换到 Sun 公司的老式 Crimson 解析器再到 Apache Xerces(版本 1 或版本 2)是非常简单的。JAXP 之类的 API 可以很轻松地实现这个过程(尽管我在侧栏中指出在所有新 API 出现之前这在 SAX 或 DOM 中就已经可用),并且在很多数据绑定 API 中,我们甚至完全意识不到正在进行的解析; 解析都隐藏在幕后。因此毫无疑问,我们可以马上使用任何想要的解析器。解析器中的灵活性被证实。
使用中的灵活性
大量的 XML API 还为我们提供了很多处理数据的方法。使用 SAX 和 DOM,能轻易地获得文档中的原始数据; 使用 JAXP 也同样可行,尽管所支持的数据可能会少一点(我之前提到过必须要执行一些操作才能处理 XML 注释或 DTD 语法之类的数据)。我们在使用某个数据绑定 API 时,可以在根本上操作 XML 文档的数据而不需 XML 的修饰。person 元素变成了Person 对象,并且我们能够使用 getAge() 获取 age 属性的值。在很多方面,您可以根据在 XML 文档中使用数据的方式以及对 XML 的了解程度来选择 API。因此使用中的灵活性证实无误。
错误处理中的灵活性
这里遇到了些许麻烦,高级 API 的一些灵活性造成了一些问题。在一些 API 中,如 Sun 的 JAXB 和所提供的数据绑定 API 中,我们都是在 XML 文档的原始字符串、元素和属性之上的几个层次上进行操作的。其结果是,如果文档中的内容格式不正确,则处理任何问题都无法具备高度的灵活性。一般而言,在遇到某种编组或非编组错误时,我们必须要修复 XML 本身并重新运行该过程(或者向调用程序抛出异常,这在本质上是相同的)。但是在真正地修复错误并从解析器中获得详细信息的方面呢?这确实不属于高级 API 的范围。因此,此处出现了一个缺陷。
操作 XML 文档中的灵活性
上面所提到的使用中的灵活性,看上去可能与操作 XML 文档中的灵活性是一样的。其实并非如此; 在很多新兴的(有些人会说是易于使用的)API 中,我们是在 XML 文档中操作数据的 — 然后有时甚至不是作为 XML 而是当作对象或者属性来进行操作的。操作 XML 文档本身意味着我们能直接更换、修改或者移除文档的一部分,并能直接处理元素名称、属性甚至注释和处理指令。
最初看来可能并不是真正需要这一级别的处理和灵活性,但是我们想到了与编程的类比。正如 C 语言和汇编语言使核心编码器在计算机编程的底层进行工作,特别是 SAX 之类的 API,和程度较轻的 DOM,使核心的 Java 和 XML 程序员几乎可以随心所欲地操作 XML 文档。就像大多数技巧都内建在 C 语言或者汇编语言中,由于这种额外的能力转化成了真正的速度、性能和一些优化,比起一些高级的 API(如 JAXB 甚至是 JDOM),使用 SAX 和 DOM 仍然能为有经验的程序员提供更多的支持。因此,虽然这些高级 API 确确实实提供了大量的优势,但是它们并没有为直接操作实际的 XML 文档提供很多的灵活性。
结束语
就是这样:我就是想考证究竟有多大的灵活性。显而易见,这篇文章并不是一篇充满了运行代码的技巧文章,因为我想知道这些天来是否有人确实使用了运行的 XML 代码,以及他们所使用的是哪种(或哪些)API。真的有数百计、数千计或者数万计的读者仍然坚持使用 SAX 和 DOM 舒适地编写着 startProcessingInstruction() 方法,或者完全使用数据绑定和辅助 API 取代了 SAX 和 DOM?我对此非常好奇,大多数 developerWork 的编辑人员同样好奇。
更重要的是,您是否认为自己仍然能够控制 XML 呢?我特别要向那些早期就开始处理 XML 的程序员提这个问题,那时 SAX 是快速读取 XML 的惟一选择,并且 DOM 是以对象的形式处理 XML 文档的惟一选择。您是否发现您自己在一个更高的级别工作?您是否对此满意?或者是否我们都已成为 Turbo Pascal 程序员,而只有少许人在他们的 ASM 终端上处理堆栈呢?
相关专题
- Java环境安装配置 (6065篇文章)
- Java编程开发手册 (8776篇文章)
- XML详解 (1588篇文章)
- Java API (111篇文章)
- Java网络及通讯编程 (711篇文章)
- Web开发 (439篇文章)
- 网民默哀国殇 QQ换装白加黑 (84次浏览)
- 盖茨:Windows 7后年上市 硬件要求低 (72次浏览)
- 作弊者的噩梦!反作弊手段的高科技化 (54次浏览)
- 微软明年发布Visual Studio “10” (39次浏览)
- 微软:10月份公布Windows 7细节 (39次浏览)
- Google第一美女总裁梅里莎梅尔 (38次浏览)
- Openoffice3.0: 微软Office的终结者? (35次浏览)
- Windows Embedded Standard 2009发布 (35次浏览)
- 心系灾区 IT企业赈灾行动 (31次浏览)
- 微软发布Windows XP/Vista安全报告 (28次浏览)



