Android解析和创建XML之学习笔记------SAX

Android解析XML的三种方式:DOM,SAM,PULL


1、DOM解析时需要将XML文件的所有内容以文档树的方式存放在内存中,所以内存的消耗比较大,特别是对于 运行的移动设备来说,因为设备资源有限,所以一般

建议采用SAX或者PULL来解析XML文件。不过,如果XML文件的内容比较小,采用这种方式也是可行的


2、SAX(Simple API for XML) 是基于事件驱动,边加载边解析。当然Android的事件机制是基于回调函数的,在读取到其他节点与内容的时候也会回调一个事件。


3、PULL解析XML 的方式与SAX解析XML的方式一样,它也是基于事件驱动的。


首先来学习一下SAX解析:


SAX解析的过程涉及到事件,有事件源和事件处理器。在SAX接口中,事件源是org.xml.sax包下的XMLR

eader,它通过parser()方法来解析XML文档,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中的ContentHandler/DTDHandler、ErrorHandler,以及EntityResolver这四个接口。


Android解析和创建XML之学习笔记------SAX_第1张图片


接口 ContentHandler

这是一个大多数 SAX 应用程序实现的主要接口:如果需要通知应用程序基本解析事件,则它将实现此接口并且使用setContentHandler 方法,向 SAX 解析器注册一个实例。解析器将使用该实例报告与基本文档相关的事件,如启动和终止元素与字符数据。

在此接口中的事件顺序非常重要,它本身可镜像文档中信息的顺序。例如,在 startElement 事件与相应的 endElement 事件之间,元素的所有内容(字符数据、处理指令和/ 或子元素)都将以一定顺序出现。

此接口与现在不推荐使用的 SAX 1.0 DocumentHandler 接口相似,但它增加了对名称空间和报告跳过的实体(在非验证的 XML 处理器中)的支持。

实现者应该注意,在 java.net 包中还有一个 ContentHandler 类;这意味着以下实现方法可能并非明智之举

	 import java.net.*;
	 import org.xml.sax.*;
 

实际上,不管怎样 "import ...*" 通常标志不简洁的编程,因此,用户应该将此作为一种功能而不是错误。



接口 ErrorHandler


如果 SAX 应用程序需要实现自定义的错误处理,则它必须实现此接口,然后使用 setErrorHandler 方法向 XML 阅读器注册一个实例。然后解析器将通过此接口报告所有的错误和警告。

警告:如果应用程序 注册 ErrorHandler,则将不报告 XML 解析错误,除了对严重的错误将抛出 SAXParseException外。为了检测有效性错误,必须注册用 error() 调用处理某些事情的 ErrorHandler。

对于 XML 处理错误,SAX 驱动器必须优先于抛出异常使用此接口:需要应用程序来决定是否对不同类型的错误和警告抛出异常。但是要注意,不要求解析器在调用 fatalError 之后继续报告另外的错误。换句话说,SAX 驱动器类可以在报告任何 fatalError 之后抛出异常。另外,解析器可以对非 XML 错误抛出适当的异常。例如,XMLReader.parse() 将对访问实体或文档的错误抛出 IOException。


方法摘要
 void error(SAXParseException exception) 
          接收可恢复的错误的通知。
 void fatalError(SAXParseException exception) 
          接收不可恢复的错误的通知。
 void warning(SAXParseException exception) 
          接收警告的通知。


接口 DTDHandler

如果 SAX 应用程序需要关于注释和未解析的实体的信息,则该应用程序实现此接口并使用 SAX 解析器的 setDTDHandler 方法向该解析器注册一个实例。解析器使用该实例向应用程序报告注释和未解析的实体声明。

注意,此接口仅包括 XML 推荐标准需要 处理器报告的 DTD 事件:注释和未解析的实体声明。

SAX 解析器可按任何顺序报告这些事件,而不管声明注释和未解析的实体时所采用的顺序;但是,必须在文档处理程序的 startDocument 事件之后,在第一个 startElement 事件之前报告所有的 DTD 事件。(如果使用 LexicalHandler,则这些事件也必须在 endDTD 事件之前报告。)

需要依靠应用程序来存储信息以备将来之用(可能用哈希表或对象树)。如果应用程序遇到了 "NOTATION"、"ENTITY" 或 "ENTITIES" 类型的属性,则可以使用它通过此接口获取的信息来查找与该属性值对应的实体和/ 或注释。


接口 EntityResolver

如果 SAX 应用程序需要实现自定义处理外部实体,则必须实现此接口并使用 setEntityResolver 方法向 SAX 驱动器注册一个实例。

然后 XML 阅读器将允许应用程序在包含外部实体之前截取任何外部实体(包括外部 DTD 子集和外部参数实体,如果有)。

许多 SAX 应用程序不需要实现此接口,但对于从数据库或其他特定的输入源中构建 XML 文档的应用程序,或者对于使用 URI 类型(而不是 URL )的应用程序,这特别有用。


基本实现思路:


1、创建SAXParserFactory 对象

2、根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器

3、根据SAXParser解析器获取事件源对象XMLReader

4、实例化一个DefaultHandler对象

5、连接事件源对象对象XMLReader到事件处理类DefaultHandler中

6、调用XMLReader的parse方法从输入源中获取的XML数据

7、通过DefaultHandler返回需要的数据集合

(当前要实现是将要解析的xml文件放到项目的assess目录下,raw,编译的时候会打包进去)

XML文件的引用方式如下;
getResources().openRawResource9(R.raw.link);

不过在导入xml文件的时候出现了乱码问题,

Android解析和创建XML之学习笔记------SAX_第2张图片

到编辑工具中,转过和自己项目一样的语言即可再重新导入






你可能感兴趣的:(Android开发)