您的位置:首页 > 其它

SAX解析XML

2016-05-17 15:47 211 查看
SAX解析XML


 

一、XML:【掌握】
1、概念:extensive markup language(可扩展的标记语言)
XML是一种通用的数据存储和交换格式,与平台无关,与编程语言无关,与操作系统无关。给数据集成和交互提供了极大的便利。
将数据格式化成XML文件后,真正实现了数据跨平台的交互和共享。在不同语言中,xml的解析方式都一样。
2、XML的解析:xml parse
对xml文件进行阅读和分析,提取出希望的数据和数据属性。在android开发中,将xml解析后,把数据放进List<Map<String, Object>>集合中是我们的最终目的。
3、XML的解析方式:

DOM(document object model  :文档对象模型)借助文档树模型对xml文档进行分析
SAX(simple API for xml  :xml的简单API)利用事件流的形式解析XML

        SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。
        所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。

PULL:利用事件流模型来解析XML

二、SAX解析xml
(一)、核心类:

SAXParserFactory
SAXParser
DefaultHandler

(二)、解析步骤:

创建SAXParserFactory类实例;
使用工厂来实例化一个SAXParser对象;
SAXParser对象执行parse解析方法即可。

(三)、核心代码

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new File(filePath) , new DefaultHandler());

(四)、DefaultHandler类中的回调方法(ContentHandler接口):
        只要为SAX提供实现ContentHandler接口的类,那么该类就可以得到通知事件(实际上就是SAX调用了该类中的回调方法)。
        因为ContentHandler是一个接口,在使用的时候可能会有些不方便,因此,SAX为其制定了一个Helper类:DefaultHandler,它实现了ContentHandler接口,但是其所有的方法体都为空,在实现的时候,只需要继承这个类,然后重写相应的方法即可。其中的抽象方法如下:

startDocument() 
startElement() 
endElement() 
characters() 
endDocument()

1、startDocument() :
        当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作,比如初始化List集合等;
2、endDocument() 
        和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作; 
3、startElement(String namespaceURI, String localName, String qName, Attributes atts) 
        当读到一个开始标签的时候,会触发这个方法。

namespaceURI就是命名空间;
localName是带命名空间前缀的标签名;
qName是不带命名空间前缀的元素节点名;
通过atts可以得到所有的属性数据(包括属性名和相应的值);

【备注:】
        SAX的一个重要特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要自己来写程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
 
4、endElement(String uri, String localName, String name) 
        这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
5、characters(char[] ch, int start, int length) 
        这个方法用来获取一个元素起始节点和一个元素结束节点之间的文本节点的内容。第一个参数为文本节点的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。 

三、原理分析
(一)、XML文件
<?xml version="1.0" encoding="UTF-8"?>
<books>
 <book id="1">
  <bookname>《Java编程思想》</bookname>
  <price>85.5</price>
 </book>
 <book id="2">
  <bookname>《Android 学习手册》</bookname>
  <price>39.0</price>
 </book>
</books>

(二)、DefaultHandler类中的回调方法执行顺序【理论顺序】

startDocument被执行了--- 
startElement被执行了---qName:books 
startElement被执行了---qName:book 
startElement被执行了---qName:bookname 
characters被执行了---content:《Java编程思想》 
endElement被执行了---qName:bookname 
startElement被执行了---qName:price 
characters被执行了---content:85.5 
endElement被执行了---qName:price 
endElement被执行了---qName:book 
startElement被执行了---qName:book 
startElement被执行了---qName:bookname 
characters被执行了---content:《Android 学习手册》 
endElement被执行了---qName:bookname 
startElement被执行了---qName:price 
characters被执行了---content:39.0 
endElement被执行了---qName:price 
endElement被执行了---qName:book 
endElement被执行了---qName:books 
endDocument被执行了---

(三)、实际执行顺序

startDocument被执行了---
startElement被执行了---qName:books
characters被执行了---content:
 
startElement被执行了---qName:book
characters被执行了---content:
 
startElement被执行了---qName:bookname
characters被执行了---content:《Java编程思想》
endElement被执行了---qName:bookname
characters被执行了---content:
 
startElement被执行了---qName:price
characters被执行了---content:85.5
endElement被执行了---qName:price
characters被执行了---content:
 
endElement被执行了---qName:book
characters被执行了---content:
 
startElement被执行了---qName:book
characters被执行了---content:
 
startElement被执行了---qName:bookname
characters被执行了---content:《Android 学习手册》
endElement被执行了---qName:bookname
characters被执行了---content:
 
startElement被执行了---qName:price
characters被执行了---content:39.0
endElement被执行了---qName:price
characters被执行了---content:
 
endElement被执行了---qName:book
characters被执行了---content:
endElement被执行了---qName:books
endDocument被执行了---
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: