现在的位置: 首页 > 综合 > 正文

[转]技巧: 有效使用 SAX InputSource

2013年01月02日 ⁄ 综合 ⁄ 共 1979字 ⁄ 字号 评论关闭

 

转自:http://www.ibm.com/developerworks/cn/xml/tips/x-tipsaxis/index.html

 

当您使用 SAX API 时,所有输入都从使用
org.xml.sax.InputSource
类开始。这个类包含在 SAX API 中,并且提供了输入规范(通过类似于文件或 I/O 流的标准 Java 构造),同时还提供一个公用的系统标识。
接着,SAX 在解析时从
InputSource
抽取这些信息,从而能够解析外部实体以及其它特定于文档来源的资源。

类似地,当您对 SAX 使用封装器(类似于 JAXP API)时,可以调用不同方法。最后,解析使用 SAX
InputSource
。例如,考虑
清单 1
中所示的代码段,它使用 JAXP 来启动 SAX 解析。


清单 1. 将 JAXP 用于 SAX 解析

 

即使输入了
java.io.File
文件,它也会在被转交给底层 SAX 实现之前转换成 SAX
InputSource
。之所以发生这个转换,是因为这个 JAXP 代码最终访问
org.xml.sax.XMLReader
类,该类只为启动解析提供
清单 2
中所示的两个特征符。


清单 2. 用于 XMLReader 的解析入口点

 

 

在此基础上,大多数 SAX 解析器实现(如 Apache Xerces)实际上将字符串系统标识转换为
InputSource
,并将它分配给接收
InputSource

parse()
版本。无论您如何编码自己的应用程序,SAX 最终都接收
InputSource
来用于解析。但是,并非所有这样处理的方法都同等地好。

为了避免您代码中出现令人不快的意外,最好直接使用 SAX
InputSource
类,而不是让 JAXP 或 SAX 为您处理这个任务。因为实现必须要处理每种可能的情况,所以您常常会看到构造
InputSource
实例的代码,类似于
清单 3
中所示。


清单 3. 一般的 InputSource 构造方法

 

 

正如您从注释中看到的,这些方法中的许多被传递了
null
参数。虽然执行这些方法不会花费很多时间,但 XML 解析应用程序中的每一秒都很关键;遗憾的是,这些不执行任何操作的方法浪费了宝贵的时间。通过自行构造
InputSource
实例,您可以将这个过程简化为一至两个方法调用,如
清单 4
所示。


清单 4. 改进 InputSource 构造

 

我还使用了
setEncoding()
方法来通知 SAX 解析器使用何种编码;在涉及国际化或使用多字节字符集的 XML 应用程序中,这一点很重要。

但是,这里产生了另一个问题:对于字符编码,用手工设置字符编码的编码与所提供的输入流(通过
java.io.InputStream

java.io.Reader
)所用的编码
不同
,这种情况很常见。如果这些编码不匹配,就可能发生各种解析问题。要避免这种情况,请始终用 Java
InputStream
创建您的
InputSource
,而不要用
Reader

String
系统标识(这些都是 JAXP API 的可能选项)。当您提供
InputStream
时,SAX 实现将流封装在
InputStreamReader
中;然后 SAX 自动从流中检测正确的字符编码。随后,您可以省略
setEncoding()
步骤,再次减少方法调用。结果是应用程序运行更快了,并且字符编码始终正确。

 

抱歉!评论已关闭.