张银的博客


Eat to live, but do not live to eat.

导航

《XML基础教程与实验指导》 第7章 SAX解析XML

Posted on 2009-04-09 22:10  张银  阅读(1748)  评论(2编辑  收藏  举报

第7章  SAX解析XML

  通过上一章的学习,我们知道基于DOM的解析器的核心是在内存中建立和XML文档相对应的树性树状结构,XML文件的标记、标记中的文本数据、实体等都会和内存中树状结构的某个节点相对应。使用DOM解析器的好处是,可以方便的操作内存中的树的节点来处理XML文档,获取自己所需要的数据。但DOM解析的不足之处在于,如果XML文件较大,或者只需要解析XML文档一部分数据,此时就会占有大量的内存空间。和DOM解析不同的是,SAX解析器不在内存中建立和XML文件相对应的树状结构数据,SAX解析器的核心是事件处理机制,具有占有内存少、效率高等特点。

本章知识要点:
掌握SAX概念和特点
熟练掌握SAX的工作机制
了解SAX常用接口
熟练掌握SAX解析XML文档的步骤
熟练掌握解析器和事件处理器的创建和使用
熟练掌握SAX处理各种应用
掌握SAX和DOM共同构建XML文档

7.1  SAX概述

  高效地解析XML数据非常重要,尤其是对于那些要处理大量数据的应用程序,这种技术尤为重要。不正确的解析会导致过度的内存消耗和过长的处理时间,从而有损于可伸缩性。SAX就是其中一种,并以快速高效解析大量XML文档而著称。

7.1.1  SAX介绍

  用于读取和操作XML文件的标准是文档对象模型(Document Object Model,DOM)。遗憾的是,DOM方法涉及读取整个文件并将该文件存储在一个树结构中,而这样可能是低效的、缓慢的,并且很消耗资源。一种替代技术就是Simple API for XML,或称为SAX,翻译过来的意思是简易应用程序编写接口。SAX允许在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。

7.1.2  工作机制

  SAX在概念上与DOM完全不同。首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。我们也可以把它称为授权事件模型。
SAX解析器装载XML文件时,它遍历XML文档并在其主机应用程序中产生事件(经由回调函数、指派函数或者任何可调用平台完成这一功能)表示这一过程。这样,编写SAX应用程序就如同采用最现代的工具箱编写GUI事件程序。

7.1.3  常用接口

  SAX是一个接口,一套API,在SAX接口里声明了处理XML文档的时候需要的方法。利用SAX编写的程序,可以快速的对数据进行操作。SAX接口中常用的接口如下所示:
Attributes接口
ContentHandler接口
DTDHandler接口
EntityResolver接口
XMLReader接口
SAX错误处理程序的基本接口

7.1.4  SAX解析器创建及使用

  SAX接口提供了解析XML文件的API,基于SAX接口的解析器这里我们称作SAX解析器。和DOM解析不同的是,SAX解析器不在内存中建立和XML文件相对应的树状结构数据。SAX解析器的核心是事件处理机制。

7.2  SAX应用

  SAX是一种基于事件驱动的API。利用SAX解析XML文档,涉及到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始和元素结束。事件处理器则负责对事件做出响应,对传递的XML数据进行处理。

7.2.1  处理文件开始与结束

  当SAX解析器解析XML文档时,解析到不同的标记会触发不同的事件。当SAX解析器开始解析XML文件时,就会报告“文件开始”事件给事件处理器,此时事件处理器会调用方法startDocument()方法,然后再陆续处理并报告其他的事件,如“开始标记”、“文本事件”等,如果解析到XML文档的结束,解析器会报告“文件结束”事件,事件处理器会调用endDocument()方法。解析器在解析XML文件的过程中,只能报告一次“文件开始”事件和“文件结束”事件。如果要实现处理“文件结束”和“文件开始”事件,需要在程序的类中重写这两个继承的方法。

7.2.2  处理指令

  该处理指令使得XML文件关联到某个层叠样式表,其路径为url。当SAX解析器处理XML文件时,如果发现XML文档中的处理指令会报告一个“处理指令”事件给事件处理器,事件处理器会调用下面的方法处理。
CMD

7.2.3  处理开始和结束标记

  在解析器解析XML文档时,如果发现了开始标记,就会触发“开始标记”事件,并向事件处理器发送一个“开始标记”事件报告。事件处理器获得发送的事件报告信息,就会调用方法。

7.2.4  处理文本数据

  XML文件中标记的内容是文本数据,当SAX解析器解析这些数据时,就报告“文本数据”事件给事件处理器,事件处理器获取事件信息后,就会调用下面的方法:
public void characters(char[] ch,int start,int length)throws SAXException

7.2.5  处理空白

  人们习惯上称标记之间的缩进区域是可忽略空白,这实际上不是很准确,应为XML文件的标记可以有文本和子标记,在这种情况下,标记之间的区域就可能包含非空白的字符内容(混合内容)。如果我们不允许标记有混合内容,即标记要么只包含有子标记要么只包含有文本数据,在这种情形下,称标记之间缩进区域是可忽略空白就比较恰当,这些空白区使得XML文件看起来更加美观,是没有价值的文本数据。

7.2.6  处理名称空间

  在XML文档中,名称空间主要是有效的区分名字相同的标记。当使用两个标记的名字相同时,它们可以通过隶属不同的名称空间来相互区分。名称空间通过声明名称空间来建立,分为有前缀的名称空间和无前缀的名称空间。

7.2.7  处理实体

  在XML文档中,利用DTD可以定义实体,然后与该DTD文件关联的XML文件可以通过实体引用使用该实体。实体又分为内部实体和外部实体,所谓内部实体就是实体的内容包含在DTD文件本身中;而外部实体是指实体的内容是DTD文件以外的其他文件。

7.2.8  SAX应用程序异常

  从上面的案例中,可以看出解析在调用parese方法时,必须使用try-catch语句来捕获SAXException异常,当SAXException异常发生时,parse方法会离开结束执行,停止解析过程。实际上,DefaultHandler类中的方法都可以抛出一个SAXException对象给解析器,比如,事件处理在调用startDocument()方法时,突然决定终止解析文件,就可以抛出一个SAXException对象给解析器,解析器将停止parse方法的执行。

7.3  SAX与DOM接口比较

  基于DOM接口的解析器,解析XML文档时,会将XML文档以树模型的方式加载到内存中。此时应用程序可以对树模型的任一个部分进行遍历和操作,通过DOM的树模型可以实现对XML文档的随机访问。这种访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM解析器把整个XML文档转化成DOM树放在了内存中,因此,当XML文档比较大或者文档结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项比较耗时的操作。所以,DOM解析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM解析器的树结构的思想与XML文档的结构相吻合,所以通过DOM树机制很容易实现随机访问。

 

example1.java
example1
example2.java
example2
example3.java
example3
example4.java
example4
example5.java
example5
example6.dtd
example6.java
example6
example7.java
example7
example8.dtd
example8.java
example8.txt
example8
example9.java
example9
example10.java
example10
example11.java
example11
example12.java
example13.java
example13
example14.java
example15.java
example 4ss
图书列表1