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

在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。

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

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

 

一、使用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方法进行解析。

 1 public class SAXPraserHelper extends DefaultHandler {
 2 
 3     final int ITEM = 0x0005;
 4 
 5     List<channel> list;
 6     channel chann;
 7     int currentState = 0;
 8 
 9     public List<channel> getList() {
10         return list;
11     }
12 
13     /*
14      * 接口字符块通知
15 */
16     @Override
17     public void characters(char[] ch, int start, int length)
18             throws SAXException {
19         // TODO Auto-generated method stub
20 // super.characters(ch, start, length);
21         String theString = String.valueOf(ch, start, length);
22         if (currentState != 0) {
23             chann.setName(theString);
24             currentState = 0;
25         }
26         return;
27     }
28 
29     /*
30      * 接收文档结束通知
31 */
32     @Override
33     public void endDocument() throws SAXException {
34         // TODO Auto-generated method stub
35         super.endDocument();
36     }
37 
38     /*
39      * 接收标签结束通知
40 */
41     @Override
42     public void endElement(String uri, String localName, String qName)
43             throws SAXException {
44         // TODO Auto-generated method stub
45         if (localName.equals("item"))
46             list.add(chann);
47     }
48 
49     /*
50      * 文档开始通知
51 */
52     @Override
53     public void startDocument() throws SAXException {
54         // TODO Auto-generated method stub
55         list = new ArrayList<channel>();
56     }
57 
58     /*
59      * 标签开始通知
60 */
61     @Override
62     public void startElement(String uri, String localName, String qName,
63             Attributes attributes) throws SAXException {
64         // TODO Auto-generated method stub
65         chann = new channel();
66         if (localName.equals("item")) {
67             for (int i = 0; i < attributes.getLength(); i++) {
68                 if (attributes.getLocalName(i).equals("id")) {
69                     chann.setId(attributes.getValue(i));
70                 } else if (attributes.getLocalName(i).equals("url")) {
71                     chann.setUrl(attributes.getValue(i));
72                 }
73             }
74             currentState = ITEM;
75             return;
76         }
77         currentState = 0;
78         return;
79     }
80 }
一,
 1 private List<channel> getChannelList() throws ParserConfigurationException, SAXException, IOException
 2     {
 3         //实例化一个SAXParserFactory对象
 4         SAXParserFactory factory=SAXParserFactory.newInstance();
 5         SAXParser parser;
 6         //实例化SAXParser对象,创建XMLReader对象,解析器
 7         parser=factory.newSAXParser();
 8         XMLReader xmlReader=parser.getXMLReader();
 9         //实例化handler,事件处理器
10         SAXPraserHelper helperHandler=new SAXPraserHelper();
11         //解析器注册事件
12         xmlReader.setContentHandler(helperHandler);
13         //读取文件流
14         InputStream stream=getResources().openRawResource(R.raw.channels);
15         InputSource is=new InputSource(stream);
16         //解析文件
17         xmlReader.parse(is);
18         return helperHandler.getList();
19     }
二,

从第二部分代码,可以看出使用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()获取本节点的值。

 1 private List<Map<String, String>> getData() {
 2         List<Map<String, String>> list = new ArrayList<Map<String, String>>();
 3         XmlResourceParser xrp = getResources().getXml(R.xml.channels);
 4 
 5         try {
 6             // 直到文档的结尾处
 7             while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {
 8                 // 如果遇到了开始标签
 9                 if (xrp.getEventType() == XmlResourceParser.START_TAG) {
10                     String tagName = xrp.getName();// 获取标签的名字
11                     if (tagName.equals("item")) {
12                         Map<String, String> map = new HashMap<String, String>();
13                         String id = xrp.getAttributeValue(null, "id");// 通过属性名来获取属性值
14                         map.put("id", id);
15                         String url = xrp.getAttributeValue(1);// 通过属性索引来获取属性值
16                         map.put("url", url);
17                         map.put("name", xrp.nextText());
18                         list.add(map);
19                     }
20                 }
21                 xrp.next();// 获取解析下一个事件
22             }
23         } catch (XmlPullParserException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         } catch (IOException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30 
31         return list;
32     }

 

三、使用Dom方式解析

基础知识:

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

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

 1 public static List<channel> getChannelList(InputStream stream)
 2     {
 3         List<channel> list=new ArrayList<channel>();
 4         
 5         //得到 DocumentBuilderFactory 对象, 由该对象可以得到 DocumentBuilder 对象
 6         DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
 7         
 8         try {
 9             //得到DocumentBuilder对象
10             DocumentBuilder builder=factory.newDocumentBuilder();
11             //得到代表整个xml的Document对象
12             Document document=builder.parse(stream);
13             //得到 "根节点" 
14             Element root=document.getDocumentElement();
15             //获取根节点的所有items的节点
16             NodeList items=root.getElementsByTagName("item");  
17             //遍历所有节点
18             for(int i=0;i<items.getLength();i++)
19             {
20                 channel chann=new channel();
21                 Element item=(Element)items.item(i);
22                 chann.setId(item.getAttribute("id"));
23                 chann.setUrl(item.getAttribute("url"));
24                 chann.setName(item.getFirstChild().getNodeValue());
25                 list.add(chann);
26             }
27             
28         } catch (ParserConfigurationException e) {
29             // TODO Auto-generated catch block
30             e.printStackTrace();
31         } catch (SAXException e) {
32             // TODO Auto-generated catch block
33             e.printStackTrace();
34         } catch (IOException e) {
35             // TODO Auto-generated catch block
36             e.printStackTrace();
37         }
38         
39         return list;
40     }

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

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

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

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

 

原文地址:http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.html

 

转载于:https://www.cnblogs.com/Miami/p/4277274.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看Eclipse中的jar包的源代码:jd-gui.exe

前面搞了很久的使用JAD&#xff0c;各种下载插件&#xff0c;最后配置好了&#xff0c;还是不能用&#xff0c;不知道怎么回事&#xff0c; 想起一起用过的jd-gui.exe这个工具&#xff0c;是各种强大啊&#xff01;&#xff01;&#xff01; 只需要把jar包直接扔进去就可以了&a…

maven scope含义的说明

compile &#xff08;编译范围&#xff09; compile是默认的范围&#xff1b;如果没有提供一个范围&#xff0c;那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用&#xff0c;同时它们也会被打包。 provided &#xff08;已提供范围&#xff09; provided 依…

此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求...

FirFox打开80以外的端口&#xff0c;会弹出以下提示&#xff1a; “此地址使用了一个通常用于网络浏览以外的端口。出于安全原因&#xff0c;Firefox 取消了该请求。”。 解决方法如下&#xff1a; 在Firefox地址栏输入about:config,然后在右键新建一个字符串键network.securit…

Java操作shell脚本

public class Exec {private static ILogger logger LoggerFactory.getLogger(Exec.class);public Exec() {super();}/*** 执行命令&#xff08;如Shell脚本&#xff09;<br>* * param cmd 操作命令* param timeout 超时时间* return 命令执行过程输出内容* * throws IO…

Mysql更新插入

在向表中插入数据的时候&#xff0c;经常遇到这样的情况&#xff1a;1. 首先判断数据是否存在&#xff1b; 2. 如果不存在&#xff0c;则插入&#xff1b;3.如果存在&#xff0c;则更新。 在 SQL Server 中可以这样处理&#xff1a; if not exists (select 1 from t where id …

信息加密之信息摘要加密MD2、MD4、MD5

对于用户数据的保密一直是各个互联网企业头疼的事&#xff0c;那如何防止用户的个人信息泄露呢&#xff1f;今天为大家介绍一种最简单的加密方式--信息摘要算法MD。它如何来保护用户的个人信息呢&#xff1f;其实很简单&#xff0c;当获得到用户的信息后&#xff0c;先对其进行…

Java 从网络上下载文件

/*** 下载文件到本地 */public static void downloadPicture(String imageUrl, String filename){ URL url;try {url new URL(imageUrl);//打开网络输入流DataInputStream dis new DataInputStream(url.openStream());//建立一个新的文件FileOutputStream fos new FileOutp…

An error was encountered while running(Domain=LaunchSerivcesError, Code=0)

今天突然遇到这样一个错误&#xff0c;编译可以通过&#xff0c;但是运行就会弹出这个错误提示&#xff1a; An error was encountered while running(DomainLaunchSerivcesError, Code0) 解决办法就是重置模拟器。 点击模拟器菜单中的Reset Contents and Settings&#xff0c;…

hdu 4091 线性规划

分析转自&#xff1a;http://blog.csdn.net/dongdongzhang_/article/details/7955136 题意 &#xff1a; 背包能装体积为N, 有两种宝石&#xff0c; 数量无限&#xff0c; 不能切割。 分别为 size1 value 1 size2 value2 问背包能装最大的价值&#xff1f; 思路 &#xff…

linux fmt命令

简单的格式化文本 fmt [option] [file-list] fmt通过将所有非空白行的长度设置为几乎相同&#xff0c;来进行简单的文本格式化 参数 fmt从file-list中读取文件&#xff0c;并将其内容的格式化版本发送到标准输出。如果不制定文件名或者用连字符&#xff08;-&#xff09;来替代…

基于 jQuery支持移动触摸设备的Lightbox插件

Swipebox是一款支持桌面、移动触摸手机和平板电脑的jquery Lightbox插件。该lightbox插件支持手机的触摸手势&#xff0c;支持桌面电脑的键盘导航&#xff0c;并且支持视频的播放。 在线预览 源码下载 简要教程 Swipebox是一款支持桌面、移动触摸手机和平板电脑的jQuery Ligh…

简化工作——我的bat文件

重启adb(radb.bat)&#xff1a; echo off call adb kill-server call adb start-server call adb remount push 一个apk(push.bat) echo off if "%1""launcher" ( call adb push 相关apk路径 system/app )else ( echo 请添加一个参数!当前有效…

js操作数据库

<script languagejavascript> function replace(v) { //容错问题&#xff0c;请读者自行进行判断。 //定义SQL语句 var sql select * from Dictionary where MainID v ; //新建数据库连接对象和数据集存取对象 var ConnDB new ActiveXObject(adodb.connection)…

Java中StringBuilder的清空方法比較

StringBuilder 没有提供clear或empty方法。清空有3种方法&#xff1a;1&#xff09;新生成一个&#xff0c;旧的由系统自己主动回收2&#xff09;使用delete3&#xff09;使用setLength 将三种方法循环1000万次&#xff0c;代码&#xff1a; 1.public class sbbm { 2. 3. st…

LinkCutTree 总结

最近学习了LinkCutTree&#xff0c;总结一下。 LinkCutTree是一种数据结构&#xff08;是Tree Decomposition中的一种&#xff09;&#xff0c;她维护的一般是无向图&#xff08;一个森林&#xff09;&#xff0c;支持连边、删边、链修改、链查询&#xff08;点属于特殊的链&am…

linux 数据转换

使用bc 可以进行不同进制之间的转换 digit100; printf "the number is : %d\n" $digit;binary$( echo "obase2;$digit" | bc );printf "result is : %s\n" $binary;digit1$( echo "obase10;ibase2;$binary" | bc );printf "bina…

PHP常用的正则表达式(有些需要调整)

平时做网站经常要用正则表达式&#xff0c;下面是一些讲解和例子&#xff0c;仅供大家参考和修改使用&#xff1a; "^\d$"  //非负整数&#xff08;正整数 0&#xff09; 顺平注: 验证输入id数值&#xff0c;不能为0 $reg1/^[1-9]\d*$/; "^[0-9]*[1-9][0-9]…

浮点数据的运算

使用bc设置scale可以进行相应的浮点运算#!/bin/bash# FileName TestBc.shdigit100;sqrt$(echo "scale3;sqrt($digit) " | bc);echo $sqrt;var$(echo "scale3;10/3" | bc);echo $var;var1$( echo "scale2;0.5*3" | bc);echo $var1;

IE(IE6/IE7/IE8)支持HTML5标签--20150216

让IE&#xff08;ie6/ie7/ie8&#xff09;支持HTML5元素&#xff0c;我们需要在HTML头部添加以下JavaScript&#xff0c;这是一个简单的document.createElement声明&#xff0c;利用条件注释针对IE来调用这个js文件。Opera&#xff0c;FireFox等其他非IE浏览器就会忽视这段代码…

linux shell 求绝对值

abs-1;printf "the number is : %d\n" $abs;printf "abs is : %d\n" $abs;if [ $abs -lt 0 ]; thenlet abs0-$abs;fiprintf "abs is : %d\n" $abs;