• 热门标签

当前位置: 主页 > 航空资料 > 计算机 >

时间:2010-08-09 13:05来源:蓝天飞行翻译 作者:admin
曝光台 注意防骗 网曝天猫店富美金盛家居专营店坑蒙拐骗欺诈消费者

• 程序保存解析器提供的L o c a t o r对象的注解。
• 当错误发生时,程序在生成S A X E x c e p t i o n之前使用L o c a t o r对象输出错误定位的有关信息。
注意应用程序必须支持没有L o c a t o r的情况,因为并不要求解析器必须提供L o c a t o r。
• 程序包括最初的“初因”异常的细节信息( N u m b e r F o r m a t E x c e p t i o n),异常被封装在
S A X P a r s e E x c e p t i o n里,也可以写一些更精确的诊断信息。
• 把Moby Dick的价格“8 . 9 9”改为“A . 9 9”,下面是用x m l 4 j解析器得到的输出:
本例中应用程序在产生异常之前生成了一条包含位置信息的消息,然后当异常在高层被捕
获时生成真正的错误消息。另一种方法是把位置信息作为异常的一部分来传递,可以通过产生
S A X P a r s e E x c e p t i o n而不是通常的S A X E x c e p t i o n做到这一点。然而应用程序必须处理没有L o c a t o r
的情况,这时产生S A X P a r s e E x c e p t i o n就不是很方便。一个替代的方法是当解析器不提供L o c a t o r
时让应用程序创建自己缺省的L o c a t o r(不包含什么有用信息)。
6. 保持上下文信息
迄今为止从两个例子中可以看出在解析处理过程中D o c u m e n t H a n d l e r一般需要保持一些上下
文信息。第一个例子是对元素累加计数;第二个例子是由D o c u m e n t H a n d l e r明确当前是否是在一
个含有c a t e g o r y = " f i c t i o n "的< b o o k >元素里。
几乎所有实际的S A X应用程序都需要保持一些此类的上下文信息。它经常适于明确当前元
素的嵌套情况,很多情况下也用于了解当前处理数据所有祖先元素的属性。
明显的数据结构是堆栈,因为堆栈很自然地在遇到元素开始标签时添加元素信息,而在遇
到元素结束标签时删除元素信息。当然堆栈需要比存储整个文档少得多的内存,因为堆栈中需
要的最大条目数就是元素的最大嵌套层数。即使在一个庞大复杂的文档里,嵌套层数也很少超
过1 0个左右。
如果更改一下对前面程序例子的要求,我们会看到堆栈是如何发挥作用的。这次允许书籍
目录包含多卷书目,每卷有一个价格并且整个集合有一个价格。在计算平均价格时,我们想知
道整个集合的价格而不是个别卷的价格。
源文档如下所示(也可以在h t t p : / / w w w. w r o x . c o m站点得到):
程序清单6 - 1 2
162使用XML 高级编程
下载
处理这种情况的方法是在程序里引入另一个标记,当遇到< v o l u m e >开始标签时设置标记,
当遇到< / v o l u m e >结束标签时取消标记;如果标记被设置了,程序将忽略< p r i c e >元素。但是这种
编程风格很快就导致了标记的增多和i f - t h e n - e l s e条件判断的复杂嵌套。更好的方法是把关于当前
打开元素的所有信息放到一个堆栈里,这样就可以按需查询。
下面是新的程序版本:
程序清单6 - 1 3
第6章SAX 1.0: XML简易API使用163 下载
164使用XML 高级编程
下载
下面是期望的输出:
看起来好像是我们费了好大力气维护这个堆栈而并没有取得多少效果。然而这是值得的。
所有实际的应用程序变得越来越复杂,拥有一个支持这种逻辑而不破坏程序结构的数据结构是
有益的。注意条件判断,如isFiction( )和i s Volume( ),现在成为应用于上下文数据结构的方法而
不是应用于当事件发生时保持的标记。随着需要判断条件数量的增多,可以编写更多这样的方
法而不增加startElement( )和endElement( )方法的复杂度。
6.3 SAX的高级特性
目前涉及到的S A X特性对9 0 %的S A X应用程序来说已经足够了。但是了解一些其他的特性是
有所帮助的,以备需要时使用。本章节给出了这些特性及其设计目标的概观。
第6章SAX 1.0: XML简易API使用165 下载
6.3.1 可选择的源输入
目前在我们的例子中,被解析的文档是以U R L的形式描述的。一般情况下,就U R L可以描
述的资源的范围而言,这已经足够了。它允许文档存于本地或远程文件中,或由We b服务器动
态生成。
1. 从字节流或字符流中获取输入
有时想把由另一个程序生成的的X M L流而不是存放于文件中的X M L提交给解析器。例如,
X M L可能是存放于关系数据库中,或者是一个E D I消息翻译程序的输出,或者是嵌入在一个非
X M L格式文件或消息中的X M L片段。你不想仅仅为了让解析器可以读取你的文档而不得不去编
写X M L文件(或安装We b服务器)。
为了处理这种情况, S A X 允许以字符流或字节流的形式提交X M L输入。S A X提供了
I n p u t S o u r c e类以生成所有可能的输入源。
例如,假设程序想解析存放于一个字符串里的X M L,它刚被通过J D B C从关系数据库中读取。
下面的代码完成上述工作:
程序清单6 - 1 4
I n p u t S o u r c e是S A X发行版提供的一个类(而不是一个接口)。应用程序可以设置源输入的许
多详细信息,这些信息是相互排斥的。包括提供U R L,R e a d e r,I n p u t S t r e a m,编码名称或一个
“公共标识”。(在S A X中的公共标识就像和在X M L自身规范中一样令人费解:没有什么线索可以
确定解析器应该对公共标识真正做些什么。但是后面会看到,应用程序可以使用公共标识。)
为什么S A X需要提供两种可选的内存数据, I n p u t S t r e a m和R e a d e r?
I n p u t S t r e a m是一个字节流。X M L标准对字节流如何转换为统一码字符流提供了许多规则,
例如包括编码属性(它是文档内容开始xml 声明的一部分)。为把字节转换成字符,完全由标准
J a v a库实现这种转换是不够好的,因为它们不理解这些规则,当然也不能指望它们读取编码属性。
如果X M L从二进制源获得,在处理完编码属性后,希望把字节流传递给解析器直接解释。
而R e a d e r是一个统一码字符流。如果已经有了字符形式的数据,我们不想仅仅为了解析器能
 
中国航空网 www.aero.cn
航空翻译 www.aviation.cn
本文链接地址:XML高级编程上(62)