• 热门标签

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

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

(2) 应用程序检测到的错误
当应用程序在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方法会产生一个S A X E x c e p t i o n,它包含对问题进行解释的适当消息。此后,解
析器就像它自己检测到错误一样进行恰当地处理。一般来说,它不会去捕获这个例外,而是相
同的例外立即从parse( )方法中退出,这样高层应用程序就可以捕获例外。
(3) 确定错误发生的位置
当解析器检测到一个X M L语法错误,它将在S A XPa r s e E x c e p t i o n对象里提供错误的详细信息。
这个对象包括错误所在的U R L、行、列(行号本身没有多大用处,因为错误可能是在一些外部
实例而不是主文档里)。当在应用程序里捕获到S A XPa r s e E x c e p t i o n,你就可以抽取这些信息展
示给用户以定位错误。
如果X M L文件相关的错误是在应用程序级被检测到(例如一个无效的日期),那么告知用户
错误发生的位置也同等重要,这时你就不能依赖S A XPa r s e E x c e p t i o n去定位错误,而是由S A X定
义一个L o c a t o r接口。S A X规范并不要求解析器提供一个L o c a t o r,但是大多数解析器提供。
在文档处理器里必须实现的一个方法是setLocator( )方法。如果解析器持有定位信息,它将
调用setLocator( )方法告知文档处理器L o c a t o r对象的位置。在文档处理器处理时间后的任何时候
它都可以查询L o c a t o r对象以得到源文档中当前坐标的详细信息。总共有三种坐标:
• 文档或当前处理的外部实体的U R L。
• URL里的行号。
第6章SAX 1.0: XML简易API使用157 下载
• 行里的列号。
所有相同的信息你当然也可以从S A X P a r s e 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,由S A X P a r s e E x c e p t i o n直接从
L o c a t o r对象里得到坐标信息—只要写下列语句:
为什么不简单地把定位信息包含于如s t a r t E l e m e n t ( )等要传递给文档处理器的事件里呢?原因
是效率:大多数应用程序只想得到出错时的定位信息,这样当不需要有关信息时可以有最小的
开销。从解析器到文档处理器的每个调用都提供定位信息是不必要的过多开销。
5. 另一个使用字符数据和属性的例子
了解完错误处理过程后,让我们开发一个稍微复杂一些的S A X应用程序实例。
现在应用程序的任务是输出目录中科幻书籍的平均价格。我们采用和前面实例相同的数据
文件(b o o k s . x m l)。
我们只关心那些含有c a t e g o r y = " f i c t i o n "属性的< b o o k >元素,而且对这些元素只需要知道它
< p r i c e >子元素的内容。先累加价格,然后清点书的数量,最后用总价格除以书的总数。
下面是应用程序的最初版本:
程序清单6 - 1 0
158使用XML 高级编程
下载
在这段代码中主要有三个要点:
• 应用程序需要保持一些上下文信息,即当前书目是否是科幻书籍。使用一个实体变量记录
有关情况,当遇到科幻书目的开始标签时就设置i s F i c t i o n为真,而遇到非科幻书目的开始
标签时就设置i s F i c t i o n为假。
• 注意字符内容如何在Java StringBuff e r里累加,直到endElement( )事件通知时才被真正处理。
这可以一举两得:解决了单个元素内容可能会被分解而分别通知的问题;同时意味着当处
理数据时,我们可以知道正在处理哪个元素。任何读到开始和结束标签时S t r i n g B u ff e r置为
空,即当应用程序遇到P C D ATA元素(只包含字符数据的元素)的结束标签时,缓冲区里
将包含该元素的字符数据。
• 当书目的价格不是一个有效数字时应用程序需要做一些智能判断。(除非X M L纲要被标准
化,不能指望让解析器做这些确认工作: D T D没有提供在元素中限制字符数据的数据类型
第6章SAX 1.0: XML简易API使用159 下载
的方法。)通过将字符串转换为数值的J a v a构造器Double (String s)报告一个例外可以发现
这种情况。有关代码捕获这个例外,发布一个描述错误的S A X E x c e p t i o n。然后用适当的错
误消息终止解析过程。
• 对X M L实例文件运行代码,产生下列输出:
但是程序还不是完美无缺的。
首先,如果输入文档不是期望的结构,程序很容易运行失败。例如如果< p r i c e >元素在
< b o o k >之外出现,或者< b o o k >中没有< p r i c e >元素,或者< p r i c e >元素有自己的子元素,程序都会
给出错误的答案。这些情况都可能会出现,因为没有D T D,或者是因为使用了不检查D T D的非
确认解析器,或者是因为文档被用非期望的其他D T D提交,或者是因为在程序写完之后D T D已
经被增强了。
其次,检测到错误时的诊断信息很不友好。用户将被告知某个书目价格不是数值,但是在
列表中可能有成千上百的书目:明确是哪个书目会更好一些。在一次程序运行中报告所有的错
误甚至会更有帮助,这样用户就不需要为每发现和纠正一个错误去运行一次程序。(实际上大多
数X M L解析器在一次运行中只报告一个语法错误,这限制了我们目前只能如此)。
在下一节里会看到如何保持更多关于元素上下文的信息,如果要做更全面的有效性确认,
这些信息是必要的。在此之前,先改进一下错误处理过程。使用L o c a t o r对象确定在源文档中错
误发生的位置并据此报告。为了清楚地说明处理过程,我们用IBM Alphaworks的x m l 4 j解析器代
替James Clark的x p解析器,它可以提供更清晰的信息。下面是修改过的程序:
程序清单6 - 11
160使用XML 高级编程
下载
第6章SAX 1.0: XML简易API使用161 下载
这个版本通过一点额外操作改进了诊断信息。修改后的应用程序做了三件事情:
 
中国航空网 www.aero.cn
航空翻译 www.aviation.cn
本文链接地址:XML高级编程上(61)