Java™ 编程语言的最新版本 Java 5.0 包括经过改进和扩展的 Java API for XML Processing(JAXP)版本。JAXP 主要增加了新的验证 API,它提供了更好的交互性,支持 XML Schema 和 RELAX NG,能够在验证的同时即时修改。经过这些改进,为 Java 开发人员提供了一种工业强度的 XML 验证解决方案。本文详细介绍这种新的 API,包括基本特性和更高级的特性。
几年来,Java API for XML Processing(JAXP)一直是一种稳定、有点儿沉闷的 API。这并不是坏事。沉闷常常意味着可靠,对软件来说总是好事。不过 JAXP 的迟钝已经让开发人员不再寻求新的特性。从 Java 1.3 到 1.4,除了支持最新版本的 SAX 和 DOM 规范以外,JAXP 没有很大变化。但是在 Java 5.0 和 JAXP 1.3 中,Sun 大大扩展了 JAXP。除了支持 XPath 以外,最值得一提的还有验证。本文详细介绍了 JAXP 1.3 的验证特性,该特性在 javax.xml.validation 包中实现。
简要的历史回顾
详细了解这种验证 API 的具体细节之前,必须充分了解 JAXP 1.3 之前验证是如何完成的。此外,显然 Sun 仍将支持过去的 DTD 验证方法,但是建议使用基于模式的新的验证 API。因此即便您义无反顾地要使用 javax.xml.validation 包,仍然需要理解使用 DTD 验证文档的方法。
本文中(而且一般来说),模式(schema) 指的是跟随一种 XML 格式的任何约束模型。XML Schema 是一种模式,但模式不一定是 XML Schema(按照 W3C 规范的定义)。比如,模式 也可用于 RELAX NG 模式。使用一般意义的模式 更便于指称某种特定的方法(基于 XML 的约束模型)而不局限于具体的实现。
创建解析器工厂
在一般的 JAXP 处理中,都是从 工厂 开始的。SAXParserFactory 用于 SAX 解析,DocumentBuilderFactory 则用于 DOM 解析。这两种工厂都使用静态方法 newInstance() 创建,如清单 1 所示。
清单 1. 创建 SAXParserFactory 和 DocumentBuilderFactory
// Create a new SAX Parser factory
SAXParserFactory factory = SAXParserFactory.newInstance();
// Create a new DOM Document Builder factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
打开验证
虽然 SAXParserFactory 和 DocumentBuilderFactory 有分别适合 SAX 和 DOM 的不同特性和性质,但是对验证来说它们都有一个共同的方法:setValidating()。如您所料,要打开验证,只需要把 true 传递给该方法。但是使用工厂是为了创建解析器而不是直接解析文档。创建工厂之后就可以调用 newSAXParser()(SAX)或 newDocumentBuilder()(DOM)。
对工厂设置的选项影响该工厂创建的所有解析器。如果用 true 调用 setValidating(),则明确地告诉工厂创建的所有解析器都必须是进行验证的。要记住,很容易出现这种情况:在工厂中打开验证,在写了 100 行代码之后忘了这个设置,也就忘了生成的解析器是进行验证的。
清单 2 显示了这两个方法,都打开了验证。
清单 2. 打开验证(DTD)
// Create a new SAX Parser factory
SAXParserFactory factory = SAXParserFactory.newInstance();
// Turn on validation
factory.setValidating(true);
// Create a validating SAX parser instance
SAXParser parser = factory.newSAXParser();
// Create a new DOM Document Builder factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Turn on validation
factory.setValidating(true);
// Create a validating DOM parser
DocumentBuilder builder = factory.newDocumentBuilder();
无论哪种情况,都将得到一个能够解析 XML 并在解析过程中验证 XML 的对象(SAXParser 或 DocumentBuilder)。但是要记住,这样做 仅 限于 DTD 解析。setValidating(true) 调用对基于 XML 的解析完全没有作用。
