曝光台 注意防骗
网曝天猫店富美金盛家居专营店坑蒙拐骗欺诈消费者
够对它重新解码,而不得不先把它作为字节流进行编码(如U T F - 8编码所要求)。最好由解析器
直接处理字节流。(实际上关于是否希望在S A X里提供这种选择还有一些争论。但是它显然很有
用处,它不完全符合X M L规范的精神,X M L规范严格定义了X M L文档为字节序列。也许最好是
不把输入字符流看作是一个X M L文档,而是当作一个经过预处理的X M L文档,该文档已经完成
了第一步处理,即字节的解码。)
对于是使用字节流还是字符流,有一个值得注意的障碍:解析器无法解析源文档中出现的
相对U R L。假设源文档包含下面这样一行:
166使用XML 高级编程
下载
到哪里去找b o o k s . d t d? X M L规范说明(事实上)应该在和源文档相同的目录下,但是当然
并没有源文档目录,因为当开始解析时它是在内存中。
S A X通过允许用字节流或字符流提交系统标识(即U R L)避免了这种情况。这个U R L不是
用于读取源文档,而只是作为一个用以解析源文档中出现的相对U R L的基础。
2. 指定文件名而不是U R L
另一个常见的输入源是文件名:例如,命令行接口一般使用文件名而不是U R L作为输入参
数,而且你可能想在应用程序接口中也使用这种形式的参数。
SAX InputSource类不直接支持为输入指定一个文件名;你必须把文件名转换成U R L以使解
析器能够处理它。如果使用Java 2 就简单了: Java File 类有一个相配的方法。要解析文件
c : \ s a m p l e . x m l,你可以写这样的语句:
(注意parse( )方法要求U R L是一个字符串而不是一个Java URL对象,因此需要调用toString( )实
现这种转换。)
对于Java 1.1,如果想让代码能够同时在Wi n d o w s和U N I X上运行,那么把文件名转换成U R L
就要比想象中的稍微困难一点,因为有很多种文件名格式。下面的方法能够处理绝大多数格式,
尽管错误处理还不完善:
程序清单6 - 1 5
3. 非X M L输入源
S A X使用的更令人惊奇的一种输入方式是把根本不是X M L形式的数据提交给应用程序。只
要数据是分层格式并可以被合理地映射到X M L数据模型,你就可以编写一个各种操作类似X M L
解析器的驱动程序。驱动程序发送如startElement( ) 和endElement( ) 的事件给应用程序的
D o c u m e n t H a n d l e r,就像数据是来源于一个X M L文档,实际上并不存在一个要解析的X M L文档。
为什么要这样做?它可以利用为接收X M L数据而编写的应用程序,而不经过先以X M L格式
编写数据然后再进行解析这种笨拙的处理过程。例如,如果有一个应用程序,程序是为处理电
第6章SAX 1.0: XML简易API使用167 下载
子商务的输入X M L - E D I消息而设计的,你也许就想编写一个转换程序,能够把比较老的专有格
式的消息提交给应用程序处理。转换程序的一种实现方法是创建一个X M L文件然后把文件提交
给应用程序。但是如果目标应用程序是为使用S A X编写的,有一个巧妙的简便方法,就是转换
程序假装是一个X M L解析器去直接调用应用程序。
下面关于S A X过滤器的章节将讨论使用这种方法的可能性。
6.3.2 处理外部实体
人们经常把在文档文本中出现的像& a u m l a u t ;形式的标志看作X M L实体。这并不完全准
确:& a u m l a u t ;严格来说不是一个实体,而是一个实体参照。实体是& a u m l a u t ;所应用的对象,这
就是D T D中的定义,此定义把“ a u m l a u t”和它的扩展文本“ ä”联系起来。
在X M L中有许多不同种类的实体,要非常谨慎地明确我们讨论的是哪种实体。如第3章中所
提到的,包括表6 - 3所列各项。
表6 - 3
实体描述
字符引用( Character references) 以数值编码(十进制或十六进制)指定的字符,如& # x a ;
或& # 1 0 ;(这些并不是严格意义上的实体,为了完备性,在
此处包含这种情况)
预定义实体( Predefined entities) X M L标准中定义的特殊的实体参照,如& l t ;和& a m p ;只是
唯一一种不需要在D T D中有相应定义(内部或外部)而使用
的实体参照
内部实体( Internal entities) 其扩展文本在D T D中定义(不作为对一些外部存储对象的
引用)
外部解析实体(External parsed entities) 其扩展文本是在一个独立文件中定义的完备的X M L形式,
该文件是从主X M L文档通过系统标识或U R L引用的
非解析实体( Unparsed entities) 包括非X M L数据(例如二进制编码图像):总是外部的。
真正的格式可以是以符号形式标识
参数实体( Parameter entities) 包括D T D而不是文档主体的组成部分
文档实体( Document entity) 主源X M L文档本身就是一个实体
外部文件类型定义( External DTD) 如果文档应用了一个外部D T D,那么D T D也是一个实体
S A X中处理实体的功能关注于解析对外部实体的引用,外部实体即存放于不同“文件”中
的数据—更严格地说,是存放于被系统标识或公共标识识别的容器中。内部实体、字符引用
和预定义实体被解析器直接处理,应用程序不能干预它们扩展的方式。
X M L中的外部实体总是由一个系统标识来识别(一个U R L或更实际的类似于U R L的东西),
或者也可以是由一个公共标识来识别。公共标识为S G M L预先考虑:尽管基于已经建立的S G M L
惯例有一些约定,XML 标准(S A X同样如此)并不真正说明公共标识用来做什么和应该如何使
用。
很多情况下,通过解释系统标识或U R L来解析外部实体引用的标准规则实际上是不够的。
这些情况包括:
• 当实体存放在数据库中(或任何其他不能直接被U R L寻址的地方,例如字处理系统中的短
168使用XML 高级编程
下载
语库)。
• 当同一个实体引用根据上下文被分别解析。例如, & c u r r e n t U s e r ;实体引用可能被扩展为当
前登录用户的名字。
中国航空网 www.aero.cn
航空翻译 www.aviation.cn
本文链接地址:
XML高级编程上(63)