从 SAX 开始

SAX (Simple API for XML)是用于处理 XML 的事件驱动方法。它基本由许多回调函数组成。例如,每当 SAX 语法分析器遇到元素的开始标记时就调用 startElement() 。对于字符串,将调用 characters() 回调函数,然后在元素结束标记处调用 endElement() 。还有很多回调函数用于文档处理、错误和其它词汇结构。现在知道这是怎么回事了。SAX 程序员实现一个定义这些回调函数的 SAX 接口。SAX 还实现一个名为 HandlerBase 的类,该类实现所有这些回调函数,并提供所有这些回调方法的缺省空实现。(提到这一点是因为它在后面讲到的 DOM 中很重要。)SAX 开发人员只需扩展这个类,然后实现需要插入特定逻辑的方法。所以,SAX 的关键在于为这些不同的回调函数提供代码,然后允许语法分析器在适当的时候触发这些回调函数中的每一个。

因此,典型的 SAX 过程如下:
用特定供应商的语法分析器实现创建一个 SAXParser 实例

注册回调实现(例如,通过使用扩展 HandlerBase 的类)

开始进行语法分析,然后在触发回调实现时等待

JAXP 的 SAX 组件提供执行所有这些步骤的简单方式。如果没有 JAXP,SAX 语法分析器要直接从供应商类(如 org.apache.xerces.parsers.SAXParser )进行实例化,或者必须使用名为 ParserFactory 的帮助类。第一个方法的问题很明显:不独立于供应商。第二个方法的问题在于 类厂需要一个自变量,即要使用的语法分析器类的字符串名称(还是那个 Apache 类 org.apache.xerces.parsers.SAXParser )。可以通过将不同语法分析器作为 String 传递来更改语法分析器。使用这种方法不必更改任何 import 语句,但是还是要重新编译类。这显然不是最佳解决方案。如果能够不重新编译类而更改语法分析器,可能会简单得多,是不是这样呢?

JAXP 提供了更好的替代方法:它允许将语法分析器作为 Java 系统属性来提供。当然,当从 Sun 下载版本时,将得到使用 Sun 语法分析器的 JAXP 实现。可以从 Apache XML Web 站点下载在 Apache Xerces 上构建其实现的相同 JAXP 接口。因此(无论哪一种情况),更改正在使用的语法分析器需要更改类路径设置,即从一种语法分析器实现更改到另一个,但是 不要求重新编译代码。这就是 JAXP 的魔力,或抽象性。

SAX 语法分析器一瞥
JAXP SAXParserFactory 类是能够轻易更改语法分析器实现的关键所在。必须创建这个类的新实例(等一会将讲到)。创建新实例之后,类厂提供一个方法来获得支持 SAX 的语法分析器。在内部,JAXP 实现处理依赖于供应商的代码,使您的代码不受影响。这个类厂还提供其它一些优秀特性。

除创建 SAX 语法分析器实例的基本工作之外,类厂还允许设置配置选项。这些选项影响所有通过类厂获得的语法分析器实例。JAXP 1.0 中两个可用的功能是设置名称空间敏感性 ( setNamespaceAware (boolean awareness)),和打开确认 ( setValidating (boolean validating))。请记住,一旦设置了这些选项,在调用该方法之后,它们将影响 所有从 类厂获得的实例。
设置了类厂之后,调用 newSAXParser() 将返回一个随时可用的 JAXP SAXParser 类实例。这个类封装了一个下层的 SAX 语法分析器(SAX 类 org.xml.sax.Parser 的实例)。它还防止向语法分析器类添加任何特定于供应商的附加功能。(还记得以前对 XmlDocument 的讨论吗?)这个类可以开始进行实际的语法分析。以下清单显示如何创建、配置和使用 SAX 类厂。