常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。最近做了一个android版的CSDN阅读器,用到了其中的两种(sax,pull),今天对android解析xml的这三种方式进行一次总结。

今天解析的xml示例(channels.xml)如下:

<?xml version="1.0" encoding="utf-8"?>
<channel>
<item id="0" url="http://www.baidu.com">百度</item>
<item id="1" url="http://www.qq.com">腾讯</item>
<item id="2" url="http://www.sina.com.cn">新浪</item>
<item id="3" url="http://www.taobao.com">淘宝</item>
</channel>

一、使用sax方式解析

基础知识:

这种方式解析是一种基于事件驱动的api,有两个部分,解析器和事件处理器,解析器就是XMLReader接口,负责读取XML文档,和向事件处理器发送事件(也是事件源),事件处理器ContentHandler接口,负责对发送的事件响应和进行XML文档处理。

下面是ContentHandler接口的常用方法

public abstract void characters (char[] ch, int start, int length)

这个方法来接收字符块通知,解析器通过这个方法来报告字符数据块,解析器为了提高解析效率把读到的所有字符串放到一个字符数组(ch)中,作为参数传递给character的方法中,如果想获取本次事件中读取到的字符数据,需要使用start和length属性。

public abstract void startDocument () 接收文档开始的通知

public abstract void endDocument () 接收文档结束的通知

public abstract void startElement (String uri, String localName, String qName, Attributes atts) 接收文档开始的标签

public abstract void endElement (String uri, String localName, String qName) 接收文档结束的标签

在一般使用中为了简化开发,在org.xml.sax.helpers提供了一个DefaultHandler类,它实现了ContentHandler的方法,我们只想继承DefaultHandler方法即可。

另外SAX解析器提供了一个工厂类:SAXParserFactory,SAX的解析类为SAXParser 可以调用它的parser方法进行解析。

看了些基础以后开始上代码吧(核心代码,下载代码在附件)

public class SAXPraserHelper extends DefaultHandler {final int ITEM = 0x0005;List<channel> list;channel chann;int currentState = 0;public List<channel> getList() {return list;}/** 接口字符块通知
*/@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {// TODO Auto-generated method stub
// super.characters(ch, start, length);String theString = String.valueOf(ch, start, length);if (currentState != 0) {chann.setName(theString);currentState = 0;}return;}/** 接收文档结束通知
*/@Overridepublic void endDocument() throws SAXException {// TODO Auto-generated method stubsuper.endDocument();}/** 接收标签结束通知
*/@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// TODO Auto-generated method stubif (localName.equals("item"))list.add(chann);}/** 文档开始通知
*/@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stublist = new ArrayList<channel>();}/** 标签开始通知
*/@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// TODO Auto-generated method stubchann = new channel();if (localName.equals("item")) {for (int i = 0; i < attributes.getLength(); i++) {if (attributes.getLocalName(i).equals("id")) {chann.setId(attributes.getValue(i));} else if (attributes.getLocalName(i).equals("url")) {chann.setUrl(attributes.getValue(i));}}currentState = ITEM;return;}currentState = 0;return;}
}
private List<channel> getChannelList() throws ParserConfigurationException, SAXException, IOException{//实例化一个SAXParserFactory对象SAXParserFactory factory=SAXParserFactory.newInstance();SAXParser parser;//实例化SAXParser对象,创建XMLReader对象,解析器parser=factory.newSAXParser();XMLReader xmlReader=parser.getXMLReader();//实例化handler,事件处理器SAXPraserHelper helperHandler=new SAXPraserHelper();//解析器注册事件xmlReader.setContentHandler(helperHandler);//读取文件流InputStream stream=getResources().openRawResource(R.raw.channels);InputSource is=new InputSource(stream);//解析文件xmlReader.parse(is);return helperHandler.getList();}

从第二部分代码,可以看出使用SAX解析XML的步骤:

1、实例化一个工厂SAXParserFactory

2、实例化SAXPraser对象,创建XMLReader 解析器

3、实例化handler,处理器

4、解析器注册一个事件

4、读取文件流

5、解析文件

二、使用pull方式解析

在android系统中,很多资源文件中,很多都是xml格式,在android系统中解析这些xml的方式,是使用pul解析器进行解析的,它和sax解析一样(个人感觉要比sax简单点),也是采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。

其实以上描述,就是对整个解析步骤的一个描述,看看代码吧

private List<Map<String, String>> getData() {List<Map<String, String>> list = new ArrayList<Map<String, String>>();XmlResourceParser xrp = getResources().getXml(R.xml.channels);try {// 直到文档的结尾处while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {// 如果遇到了开始标签if (xrp.getEventType() == XmlResourceParser.START_TAG) {String tagName = xrp.getName();// 获取标签的名字if (tagName.equals("item")) {Map<String, String> map = new HashMap<String, String>();String id = xrp.getAttributeValue(null, "id");// 通过属性名来获取属性值map.put("id", id);String url = xrp.getAttributeValue(1);// 通过属性索引来获取属性值map.put("url", url);map.put("name", xrp.nextText());list.add(map);}}xrp.next();// 获取解析下一个事件}} catch (XmlPullParserException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}

三、使用Dom方式解析

基础知识:

最后来看看Dom解析方式,这种方式解析自己之前也没有用过(在j2ee开发中比较常见,没有做过这方面的东西),在Dom解析的过程中,是先把dom全部文件读入到内存中,然后使用dom的api遍历所有数据,检索想要的数据,这种方式显然是一种比较消耗内存的方式,对于像手机这样的移动设备来讲,内存是非常有限的,所以对于比较大的XML文件,不推荐使用这种方式,但是Dom也有它的优点,它比较直观,在一些方面比SAX方式比较简单。在xml文档比较小的情况下也可以考虑使用dom方式。

Dom方式解析的核心代码如下:

public static List<channel> getChannelList(InputStream stream){List<channel> list=new ArrayList<channel>();//得到 DocumentBuilderFactory 对象, 由该对象可以得到 DocumentBuilder 对象DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();try {//得到DocumentBuilder对象DocumentBuilder builder=factory.newDocumentBuilder();//得到代表整个xml的Document对象Document document=builder.parse(stream);//得到 "根节点" Element root=document.getDocumentElement();//获取根节点的所有items的节点NodeList items=root.getElementsByTagName("item");  //遍历所有节点for(int i=0;i<items.getLength();i++){channel chann=new channel();Element item=(Element)items.item(i);chann.setId(item.getAttribute("id"));chann.setUrl(item.getAttribute("url"));chann.setName(item.getFirstChild().getNodeValue());list.add(chann);}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}

总结一下Dom解析的步骤(和sax类似)

1、调用 DocumentBuilderFactory.newInstance() 方法得到 DOM 解析器工厂类实例。

2、调用解析器工厂实例类的 newDocumentBuilder() 方法得到 DOM 解析器对象

3、调用 DOM 解析器对象的 parse() 方法解析 XML 文档得到代表整个文档的 Document 对象。

四、总结

除以上三种外还有很多解析xml的方法,比如DOM4J、JDOM等等。但其基本的解析方式包含两种,一种是事件驱动的(代表SAX),另一种方式是基于文档结构(代表DOM)。其他的只不过语法不一样而已。

Android之解析XML总结(SAX、Pull、Dom三种方式)相关推荐

  1. XML文档定义有几种形式?解析XML文档有哪几种方式?

    XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? a: 两种形式 dtd schema,b: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上 ...

  2. XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

    XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? XML文档定义分为DTD和Schema两种形式,二者都是对XML语法的约束.其本质区别在于Schema本身也是一个XML文 ...

  3. Android App监听软键盘按键的三种方式与改变软键盘右下角确定键样式

    Android App监听软键盘按键的三种方式与改变软键盘右下角确定键样式 actionNone : 回车键,按下后光标到下一行 actionGo : Go, actionSearch : 放大镜 a ...

  4. android double转string_Java 数组转 List 的三种方式及对比

    来源:Java数组转List的三种方式及对比_五道口-CSDN博客 作者:大脑补丁 前言: 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解 ...

  5. android解析XML总结(SAX、Pull、Dom三种方式)

    在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX.Pull.Dom解析方式. 今天解析的xml示例(channels.xml)如下: 1 <?xml v ...

  6. XML文档定义有几种方式?它们之间有何本质区别?解析XML文档有哪几种方式?

    XML文档定义方式:有两种定义形式,dtd文档类型定义和schema模式 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的) 普通区别: 1.s ...

  7. Java - XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net XML文档定义分为DTD和Schema两种形式,二者 ...

  8. Android实现加载(loading)图片旋转的三种方式

    我们在Android应用开发中可能经常用到类似如下效果的加载过程中的图片旋转效果: 上面的图片是一张gif格式的动态图片,我们知道,在Android中对gif动态图片的支持是不好的.可以通过第三方ja ...

  9. Android App监听软键盘按键的三种方式(转)

    最近有类似需求,在csdn上刚好发现,粘贴过来,以防止忘记喽 前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的&quo ...

最新文章

  1. Asp.net控件开发学习笔记(三)-控件开发基础
  2. Uva 10074【递推dp】
  3. 当前上下文中不存在viewbag
  4. Matlab2012a下配置LibSVM—3.18
  5. MVC框架浅析(基于PHP)
  6. python中库是什么意思_python的库是什么意思
  7. 转:springboot servlet使用配置
  8. 常见Java错误的十大列表(前100名!)
  9. 洛谷 P1356 数列的整除性
  10. SpringCloud创建Config读取本地配置
  11. Spring Boot学习总结(15)——Spring Boot优缺点再总结
  12. 全球信息产业的云转型浪潮
  13. (实用工具分享)网页元素截图工具
  14. 网站漏洞修复方案防止SQL注入攻击漏洞
  15. Ubuntu 安装hadoop 伪分布式
  16. mysql 一对多约束条件_MySQL数据库/约束条件与表关系.md · 静谧之裳/python-learn - Gitee.com...
  17. 分享几个java小程序代码
  18. 大学本科数学专业课程
  19. LOTO课6:一只三极管的输出特性曲线的测绘
  20. matlab tdb,计算相图中的TDB文件 - 计算模拟 - 小木虫 - 学术 科研 互动社区

热门文章

  1. 小米开招.NET,20~40k*16薪,点名要求WPF+自动化!
  2. 记一次 .NET 某HIS系统后端服务 内存泄漏分析
  3. 有温度的技术,改善上亿人的生活
  4. 服务器重新部署踩坑记
  5. 《ASP.NET Core 真机拆解》 送书活动结果公布
  6. MassTransit Get Started-
  7. 使用Azure DevOps Pipeline实现.Net Core程序的CI
  8. .NET Core HttpClient源码探究
  9. 2019(dotNet全栈开发)公众号回顾
  10. asp.net core 自定义基于 HttpContext 的 Serilog Enricher