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.pswp.cn/news/273404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273404.shtml
英文地址,請注明出處:http://en.pswp.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;