IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

技巧: 设置 SAX 解析器

在 SAX 解析器中使用属性和功能

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

Brett McLaughlin (brett@oreilly.com), 作家, O'Reilly and Associates

2003 年 9 月 01 日

本文是技巧文章系列的第一篇文章,这些技巧文章将作为在 Java 编程语言中使用 XML 的综合指南。 我从讨论 SAX API 开始。本篇技巧文章回顾了如何获取 SAX 解析器实例以及如何对该解析器设置各种功能和属性。

在 Java 中使用 XML 是一个内容相当丰富的主题;可以使用多个 API,而且许多 API 使得使用 XML 简单得如同从文本文档读取行。 基于树的 API(如 DOM)展现了一个内存中的 XML 结构,该结构对于 GUI 和编辑器来说是最理想的, 基于流的 API(如 SAX)对于只需要获取文档数据的高性能应用程序来说很重要。 在本技巧文章系列中,我将从基础知识开始一步步地教您如何在 Java 中使用 XML。 同时,您将学习许多甚至连众多专业人士都不知道的诀窍,所以即使您已经具有一些 XML 经验,也应该仔细阅读本教程。

我从 SAX(Simple API for XML)开始。虽然该 API 或许是 Java 和 XML API 中最难以掌握的, 但它可能也是功能最强的 API。另外,大多数其它 API 实现(象 DOM 解析器、JDOM 和 dom4j 等)都部分地基于 SAX 解析器。 对于用 XML 和 Java 语言所做的每一件事情,理解 SAX 会给予您一个良好的开端。 特别在本篇技巧文章中,我将讨论如何获取 SAX 解析器实例以及如何对该解析器设置一些基本功能和属性。

:我假设您已经下载了一个符合 SAX 的解析器(如 Apache Xerces-J)(请参阅 参考资料以获取链接)。Apache 站点有大量关于如何进行设置的信息,但是,基本上您只需要将已下载的 JAR 文件放入 CLASSPATH 中。这些示例假设您的解析器可用。

获取解析器

使用 SAX 的第一步实际上是获取解析器实例。 在 SAX 中,由 org.xml.sax.XMLReader 类的实例表示解析器。我在上一篇技巧文章(“Achieving vendor independence with SAX”— 请参阅 参考资料)中对它进行了详细讨论,所以我将不会在这里花大量的时间在上面。 清单 1 显示了在无需编写与供应商相关的代码的情况下获取新 SAX 解析器实例的正确方法。


清单 1. 获取 SAX 解析器实例
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 

通过使用这个方法,您需要将系统属性 org.xml.sax.driver 设置成想要装入的解析器的类名。这是特定于供应商的类;对于 Xerces,它应该是 org.apache.xerces.parsers.SAXParser 。用 -D 开关将这个参数指定给 Java 编译器:

java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser some.sample.Class

当然,您要确保指定的类存在并在类路径上。





回页首


功能

一旦有了解析器实例,就需要配置它。 请注意,这与设置解析器来处理 XML 中的错误、内容或结构不同;相反,配置是实际告诉解析器如何操作的过程。 您可以打开验证、关闭名称空间检查及扩展实体。这些行为完全独立于特定的 XML 文档,因此涉及与新解析器实例的交互。

注:对于那些过于急燥的人来说(我知道您不是这样的),我当然会处理内容、错误处理及类似的东西。 然而,这些主题将在未来的技巧文章中讨论,所以您还得复查。眼下,我们只关注配置、功能和属性。

可以用两种方法配置解析器:功能和属性。 功能包括打开或关闭特定功能,比如验证。 属性包括设置解析器所使用的特定项的值,如用来验证所有文档的模式位置。我将先讨论功能,然后在下一节研究属性。

功能是通过解析器上名为 setFeature() 的方法设置的,这一点并不奇怪。语法类似于清单 2 所示。


清单 2. 设置 SAX 解析器的功能
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 
String featureName = "some feature URI";
boolean featureOn = true;
try {
  parser.setFeature(featureName, featureOn);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}

这相当清楚,不需要说明;关键是知道可用于 SAX 解析器的常见功能。 每个功能均由一个特定的 URI 标识。可以从 SAX 网站在线获得这些 URI 的完整列表(请参阅 参考资料)。 一些最常见的功能是验证和名称空间处理。清单 3 显示了设置这两种属性的示例。


清单 3. 一些常见功能
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 
try {
  // Turn on validation
  parser.setFeature("http://xml.org/sax/features/validation", true);
  // Ensure namespace processing is on (the default)
  parser.setFeature("http://xml.org/sax/features/namespaces", true);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}

请注意,虽然解析器有几个标准 SAX 功能,但 这些解析器可以自由地添加自己的特定于供应商的功能。例如,Apache Xerces-J 添加了一些考虑动态验证以及遇到致命错误之后继续处理的功能。请参考解析器供应商的文档,以获取相关的功能 URI。





回页首


属性

一旦理解了功能,就很容易理解属性。 除了属性将对象作为参数而功能获取布尔值外,它们以完全相同的方式操作。 我们使用 setProperty() 方法来设置属性,如清单 4 所示。


清单 4. 设置 SAX 解析器的属性
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 
String propertyName = "some property URI";
try {
  parser.setProperty(propertyName, obj-arg);
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown property specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported property specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting property: " + e.getMessage());
}

这里使用相同的错误处理框架,所以您可以容易地在两种类型的配置选项之间复制代码。 和功能一样,SAX 提供了一组标准属性,供应商可以添加他们自己的扩展。 常见的 SAX 标准的属性考虑到了设置词法处理程序(Lexical Handler)和声明处理程序(Declaration Handler)(我将在以后的技巧文章中讨论这两个处理程序)。像 Apache Xerces 之类的解析器对它们进行了扩展,例如,使它们能够设置输入缓冲区大小以及要在验证中使用的外部模式的位置。清单 5 显示了几个实际使用中的属性。


清单 5. 一些常见属性
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); 
try {
  // Set the chunk to read in by SAX
  parser.setProperty("http://apache.org/xml/properties/input-buffer-size", 
      new Integer(2048));
  // Set a LexicalHandler
  parser.setProperty("http://xml.org/sax/properties/lexical-handler", 
      new MyLexicalHandler());
} catch (SAXNotRecognizedException e) {
  System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
  System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
  System.err.println("Error in setting feature: " + e.getMessage());
}

通过理解功能和属性,您几乎可以让解析器做任何事情。 一旦掌握了用这种方式来设置解析器,您就可以准备阅读我的下一篇技巧文章,该文章将讨论有关构建基本内容处理程序方面的知识。 到那时,我们将在 XML and Java technology 论坛上再见。



参考资料



关于作者

Brett McLaughlin 的照片

Brett McLaughlin自从流行 Logo 语言时就一直从事计算机行业(记得小三角形吗?)。目前,他专门从事使用与 Java 相关的技术来构建应用程序基础结构的工作。 最近几年,他在 Nextel Communications and Allegiance Telecom, Inc. 从事这些基础结构的实现。Brett 是 Java Apache 项目 Turbine 的共同创始人之一,该项目通过使用 Java servlet 为 Web 应用程序开发构建可重用组件体系结构。 他还是 EJBoss 项目(一种开放源码 EJB 应用程序服务器)和 Cocoon(一种开放源码 XML Web 发布引擎)的志愿开发者。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款