android 解析XML方式(二)
上一节中,我们使用DOM方式解析xml文档,该方式比较符合我们日常思维方式,容易上手,但是它直接把文档调入内存中,比较耗内存。在这里我们可以用另外一种方式解析xml,这个就是SAX方式。
SAX即是:Simple API for XML
SAX是基于事件驱动的。当然android的事件机制是基于回调函数的,在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。
既然涉及到事件,就有事件源,事件处理器。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口
XMLReader通过相应事件处理器注册方法setXXXX()来完成的与ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口的连接,详细介绍请见下表:

但是我们无需都继承这4个接口,SDK为我们提供了DefaultHandler类来处理,DefaultHandler类的一些主要事件回调方法如下:

由以上可知,我们需要XmlReader 以及DefaultHandler来配合解析xml。
处理思路是:
1:创建SAXParserFactory对象
2: 根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器
3:根据SAXParser解析器获取事件源对象XMLReader
4:实例化一个DefaultHandler对象
5:连接事件源对象XMLReader到事件处理类DefaultHandler中
6:调用XMLReader的parse方法从输入源中获取到的xml数据
7:通过DefaultHandler返回我们需要的数据集合。
代码如下:
public List<River> parse(String xmlPath){
List<River> rivers=null;
SAXParserFactory factory=SAXParserFactory.newInstance();
try {
SAXParser parser=factory.newSAXParser();
//获取事件源
XMLReader xmlReader=parser.getXMLReader();
//设置处理器
RiverHandler handler=new RiverHandler();
xmlReader.setContentHandler(handler);
//解析xml文档
//xmlReader.parse(new InputSource(new URL(xmlPath).openStream()));
xmlReader.parse(new InputSource(this.context.getAssets().open(xmlPath)));
rivers=handler.getRivers();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return rivers;
}
重点在于DefaultHandler对象中对每一个元素节点,属性,文本内容,文档内容进行处理。
前面说过DefaultHandler是基于事件处理模型的,基本处理方式是:当SAX解析器导航到文档开始标签时回调startDocument方法,导航到文档结束标签时回调endDocument方法。当SAX解析器导航到元素开始标签时回调startElement方法,导航到其文本内容时回调characters方法,导航到标签结束时回调endElement方法。
根据以上的解释,我们可以得出以下处理xml文档逻辑:
1:当导航到文档开始标签时,在回调函数startDocument中,可以不做处理,当然你可以验证下UTF-8等等。
2:当导航到rivers开始标签时,在回调方法startElement中可以实例化一个集合用来存贮list,不过我们这里不用,因为在构造函数中已经实例化了。
3:导航到river开始标签时,就说明需要实例化River对象了,当然river标签中还有name ,length属性,因此实例化River后还必须取出属性值,attributes.getValue(NAME),同时赋予river对象中,同时添加为导航到的river标签添加一个boolean为真的标识,用来说明导航到了river元素。
4:当然有river标签内还有子标签(节点),但是SAX解析器是不知道导航到什么标签的,它只懂得开始,结束而已。那么如何让它认得我们的各个标签呢?当然需要判断了,于是可以使用回调方法startElement中的参数String localName,把我们的标签字符串与这个参数比较下,就可以了。我们还必须让SAX知道,现在导航到的是某个标签,因此添加一个true属性让SAX解析器知道。因此
5:它还会导航到文本内标签,(就是<img></img>里面的内容),回调方法characters,我们一般在这个方法中取出就是<img></img>里面的内容,并保存。
6:当然它是一定会导航到结束标签</river> 或者</rivers>的,如果是</river>标签,记得把river对象添加进list中。如果是river中的子标签</introduction>,就把前面设置标记导航到这个标签的boolean标记设置为false.
按照以上实现思路,可以实现如下代码:
/**导航到开始标签触发**/
public void startElement (String uri, String localName, String qName, Attributes attributes){
String tagName=localName.length()!=0?localName:qName;
tagName=tagName.toLowerCase().trim();
//如果读取的是river标签开始,则实例化River
if(tagName.equals(RIVER)){
isRiver=true;
river=new River();
/**导航到river开始节点后**/
river.setName(attributes.getValue(NAME));
river.setLength(Integer.parseInt(attributes.getValue(LENGTH)));
}
//然后读取其他节点
if(isRiver){
if(tagName.equals(INTRODUCTION)){
xintroduction=true;
}else if(tagName.equals(IMAGEURL)){
ximageurl=true;
}
}
} /**导航到结束标签触发**/
public void endElement (String uri, String localName, String qName){
String tagName=localName.length()!=0?localName:qName;
tagName=tagName.toLowerCase().trim(); //如果读取的是river标签结束,则把River添加进集合中
if(tagName.equals(RIVER)){
isRiver=true;
rivers.add(river);
}
//然后读取其他节点
if(isRiver){
if(tagName.equals(INTRODUCTION)){
xintroduction=false;
}else if(tagName.equals(IMAGEURL)){
ximageurl=false;
}
}
} //这里是读取到节点内容时候回调
public void characters (char[] ch, int start, int length){
//设置属性值
if(xintroduction){
//解决null问题
river.setIntroduction(river.getIntroduction()==null?"":river.getIntroduction()+new String(ch,start,length));
}else if(ximageurl){
//解决null问题
river.setImageurl(river.getImageurl()==null?"":river.getImageurl()+new String(ch,start,length));
}
}
运行结果如下:

android 解析XML方式(二)的更多相关文章
- android 解析XML方式(三)
上一节中,我们使用SAX方式解析xml文档, SAX方式是基于事件驱动的.当然android的事件机制是基于回调函数的.在这一节中,我们用另外一种方式解析xml文档,这种方式也是基于事件驱动的,与SA ...
- android 解析XML方式(一)
在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xml,xml是与平台无关的特性,被广泛运用于数据通信中,那么在android中如何解析xml文件数据呢? ...
- android解析XML总结(SAX、Pull、Dom三种方式) <转载>
android解析XML总结(SAX.Pull.Dom三种方式) http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.htm ...
- android解析xml文件的方式
android解析xml文件的方式 作者:东子哥 ,发布于2012-11-26,来源:博客园 在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...
- Android解析WindowManagerService(二)WMS的重要成员和Window的添加过程
前言 在本系列的上一篇文章中,我们学习了WMS的诞生,WMS被创建后,它的重要的成员有哪些?Window添加过程的WMS部分做了什么呢?这篇文章会给你解答. 1.WMS的重要成员 所谓WMS的重要成员 ...
- Android几种解析XML方式的比较
https://blog.csdn.net/isee361820238/article/details/52371342 一.使用SAX解析XML SAX(Simple API for XML) 使用 ...
- Android解析XML(PULL方式)
PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDocu ...
- Android 解析XML—pull解析方式
在Android中,常见的XML解析器分别为SAX解析器.DOM解析器和PULL解析器,其中PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部 ...
- Android解析XML
在Android平台上可以使用Simple API for XML(SAX) . Document Object Model(DOM)和Android附带的pull解析器解析XML文件. 下面是本例子 ...
随机推荐
- QQ截图工具提取
今晚关了QQ,突然想截个图,但是呢又不想打开QQ了,于是在网上搜索截图工具,下载了几个,感觉都没有QQ截图好用.索性直接百度QQ截图工具提取,看到有些网站上有提取的,里面的文件有点多,不是我中意的,突 ...
- 2016.10.30 济南学习 Day2 下午 T1
他 [问题描述] 一张长度为N的纸带,我们可以从左至右编号为0 − N(纸带最左端标号为 0).现在有M次操作,每次将纸带沿着某个位置进行折叠,问所有操作之后纸带 的长度是多少. [输入格式] 第一行 ...
- Crusher Django 学习笔记4 使用Model
http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial4-using-basic.html 顺便学习一下FQ Crush ...
- TDirectory.CreateDirectory 完整、严谨的创建一个目录
描述:创建一个目录,不包含多级目录(多级目录使用System.SysUtils.ForceDirectories,Vcl.FileCtrl.ForceDirectories已过时) procedure ...
- XAML 概述四
这一节我们来简单介绍一下XAML的加载和编译,它包括如下三种方式: · 只使用代码 · 使用代码和未编译的XAML · 使用代码和编译过的BAML 一. 只使用代码 我们首先创建一个简单的控制台 ...
- .NET特性-Attribute
两篇文章有助于学习Attribute特性的概念. http://blog.csdn.net/byondocean/article/details/6802111 http://www.cnblogs. ...
- Oracle中的通配符
这是scott用户下的EMP表 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7369 SMITH CLERK 7902 1980/12/17 800 ...
- CentOS 7.0安装MPlayer
自带的播放器不管rmvb还是mp4都不能播放,也搜索不到解码器. CentOS7epel装不上所以也没有rpmfusion,所以决定自己编译mplayer 首先是要获取源代码. 首先是主程序的源代码. ...
- 常见前端面试题之HTML/CSS部分
转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html Doctype是什么?如何触发严格模式与混杂模式模式?区分它们有何意义? ...
- 第一章 Web MVC简介
Web MVC简介 1.1.Web开发中的请求-响应模型: 在Web世界里,具体步骤如下: 1. Web浏览器(如IE)发起请求,如访问hao123主页 2. Web服务器(如Tomcat)接收请 ...