Android平臺(tái)基于Pull方式對(duì)XML文件解析與寫(xiě)入方法詳解
本文詳細(xì)講述了Android平臺(tái)基于Pull方式對(duì)XML文件解析與寫(xiě)入方法。分享給大家供大家參考,具體如下:
XML技術(shù)在跨平臺(tái)的情況下的數(shù)據(jù)交互中得到了廣泛的應(yīng)用,假如我們需要開(kāi)發(fā)一個(gè)Android應(yīng)用程序,需要同服務(wù)器端進(jìn)行數(shù)據(jù)交互,通過(guò)XML文件可以很方便的在Android平臺(tái)和服務(wù)器之間進(jìn)行數(shù)據(jù)傳輸,具體實(shí)現(xiàn)涉及到對(duì)XML文件進(jìn)行解析及寫(xiě)入的技術(shù)。本文實(shí)現(xiàn)在Android平臺(tái)上基于Pull方式對(duì)XML文件解析的技術(shù)。
XmlPullParser是一個(gè)Java實(shí)現(xiàn)的開(kāi)源API包(源碼下載地址http://www.xmlpull.org/),實(shí)現(xiàn)了pull方式解析xml文件的方法, Android SDK中包含了該API,使用時(shí)需要導(dǎo)入以下三個(gè)包:
import org.xmlpull.v1.XmlPullParser;//包含解析XML文件類(lèi)的包 import org.xmlpull.v1.XmlPullParserException;//處理異常 importorg.xmlpull.v1.XmlSerializer;//包含寫(xiě)入XML文件類(lèi)的包
我們以SQLite數(shù)據(jù)庫(kù)課堂練習(xí)中的數(shù)據(jù)類(lèi)People為例,People類(lèi)有4個(gè)屬性:ID,Name,Age,Height,假設(shè)有一條測(cè)試數(shù)據(jù)ID=1,Name=”杜甫”,Age=30,Height=1.75,
在XML文件中對(duì)應(yīng)的數(shù)據(jù)項(xiàng)元素如下:
<peopleinfo>
<peopletag="item1">
<id>1</id>
<name>杜甫</name>
<age>30</age>
<height>1.75</height>
</people>
</peopleinfo>
1. 使用XmlPullParser對(duì)該文件解析
首先需要初始化一個(gè)XmlPullParser對(duì)象parser,R.xml.peopleinfo為文件peopleinfo.xml在項(xiàng)目中的標(biāo)識(shí),讀入該文件后一步一步對(duì)文件中的元素進(jìn)行解析。
XmlPullParser parser= getResources().getXml(R.xml.peopleinfo);
XmlPullParser的相關(guān)函數(shù)及說(shuō)明如下:
|
相關(guān)函數(shù)或變量 |
說(shuō)明 |
示例 |
|
XmlPullParser.START_DOCUMENT |
文檔開(kāi)始標(biāo)識(shí),根元素 |
<peopleinfo> |
|
XmlPullParser.END_DOCUMENT |
文檔結(jié)束標(biāo)識(shí) |
</peopleinfo> |
|
XmlPullParser.START_TAG |
元素開(kāi)始標(biāo)識(shí) |
<people> |
|
XmlPullParser.END_TAG |
元素結(jié)束標(biāo)識(shí) |
</people> |
|
getEventType() |
獲取當(dāng)元素的類(lèi)型 (如START_TAG, END_TAG, TEXT, etc.) |
如<peopleinfo> 的類(lèi)型為START_DOCUMENT |
|
next() |
獲取下一個(gè)待解析元素 |
事件表示<>括號(hào)中的一個(gè)項(xiàng) |
|
getName() |
獲取當(dāng)前元素的名字 |
如讀取到<age>,返回值為”age” |
|
nextText() |
返回當(dāng)前元素所對(duì)應(yīng)的文本值 |
如事件為<height>時(shí),返回1.75 |
|
getAttributeName(int index) |
獲取當(dāng)前元素中屬性名 |
如tag |
|
getAttributeValue(int index) |
獲取當(dāng)前元素中屬性的值 |
如"item1" |
解析步驟:
1) 初始化parser,指定xml文件
2) 讀取文檔開(kāi)始標(biāo)識(shí),根元素<peopleinfo>
3) 讀取數(shù)據(jù)項(xiàng)元素開(kāi)始標(biāo)識(shí), <people>
a) 讀取數(shù)據(jù)項(xiàng)元素的屬性,tag="item1"
b) 讀取數(shù)據(jù)項(xiàng)的子元素,id,name,age,height
4) 一個(gè)數(shù)據(jù)項(xiàng)結(jié)束,</people>,保存該數(shù)據(jù)項(xiàng)的結(jié)果
5) 讀取文檔結(jié)束標(biāo)識(shí),</peopleinfo>
2. 使用XmlSerializer對(duì)寫(xiě)XML文件
寫(xiě)入XML文件的過(guò)程:先初始化一個(gè)XmlSerializer對(duì)象serializer,設(shè)置輸出的Writer對(duì)象,然后數(shù)據(jù)寫(xiě)入serializer中,再將該對(duì)象通過(guò)Writer寫(xiě)入文件。
XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(writer); //… writer.flush()
XmlSerializer的相關(guān)函數(shù)及說(shuō)明如下:
|
相關(guān)函數(shù) |
說(shuō)明 |
示例 |
|
設(shè)置輸出的Writer對(duì)象 |
|
|
|
寫(xiě)入XML文件的起始標(biāo)識(shí)語(yǔ)句,必須在setOutput后被調(diào)用 |
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
|
|
寫(xiě)入開(kāi)始元素標(biāo)識(shí) |
如<people>,<age> |
|
|
|
如tag=”people1” |
|
|
text(String text) |
寫(xiě)入元素值 |
如:杜甫 |
|
寫(xiě)入元素結(jié)束標(biāo)識(shí) |
如</people>,</age> |
|
|
endDocument(); |
寫(xiě)入文檔結(jié)束標(biāo)記 |
|
寫(xiě)入步驟:
1) 初始化serializer
2) 設(shè)置Writer對(duì)象writer
3) 寫(xiě)入文檔開(kāi)始標(biāo)記<?xml version="1.0" encoding="UTF-8"standalone="yes" ?>
4) 寫(xiě)入根元素<peopleinfo>
5) 寫(xiě)入數(shù)據(jù)項(xiàng)元素<people>
a) 寫(xiě)入數(shù)據(jù)項(xiàng)屬性tag=”people1”
b) 寫(xiě)入數(shù)據(jù)項(xiàng)子元素,id,name,age,height
6) 寫(xiě)入數(shù)據(jù)項(xiàng)元素結(jié)束符</people>
7) 寫(xiě)入根元素結(jié)束符</peopleinfo>
8) 寫(xiě)入文檔結(jié)束符
9) 通過(guò)writer將數(shù)據(jù)寫(xiě)入文件,writer.flush()
10) 關(guān)閉writer對(duì)象
實(shí)現(xiàn)工具類(lèi)XmlPullHelper,提供對(duì)XML文件解析和寫(xiě)入的
1. 具體實(shí)現(xiàn),代碼如下:
package aaron.android.SQLiteDamon;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.util.Log;
public class XmlPullHelper {
private XmlPullParser parser;
private XmlSerializer serializer;
private ArrayList<Map<String, Object>> contents=new ArrayList<Map<String,Object>>();
private Map<String,Object> map=null;
public XmlPullHelper(XmlPullParser parser,XmlSerializer serial){
this.parser=parser;
this.serializer = serial;
}
/**
* 將xml文件中的所有節(jié)點(diǎn)的數(shù)據(jù)解析后保存在一個(gè)ArrayList中返回
* @param nodeName:數(shù)據(jù)項(xiàng)的名稱(chēng),這里為"people"
* @param attr:數(shù)據(jù)項(xiàng)的屬性,如id,name,age,height
* @return 解析該xml文件數(shù)據(jù)的結(jié)果
* @throws XmlPullParserException
* @throws IOException
*/
public ArrayList<Map<String,Object>> xmlPull(String nodeName,String[] attr) throws XmlPullParserException, IOException{
//循環(huán)讀取所有的元素
while(parser.next()!=XmlPullParser.END_DOCUMENT){
switch(parser.getEventType()){
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:{ //元素開(kāi)始標(biāo)識(shí)
//判斷是否為所需要的數(shù)據(jù)項(xiàng),如果是,在初始化一個(gè)map用于保存該數(shù)據(jù)項(xiàng)的值
if(parser.getName()!=null&&parser.getName().equals(nodeName)){
map=new HashMap<String, Object>();
//循環(huán)讀取該元素中所有的屬性
for(int j=0;j<parser.getAttributeCount();j++)
map.put(parser.getAttributeName(j), parser.getAttributeValue(j));//添加屬性的值,如tag="item1"
}
else if(map!=null){
for(int i=0;i<attr.length;i++){
if(parser.getName()!=null&&parser.getName().equals(attr[i])){//添加子元素的值,如<name>張三</name>
map.put(attr[i],parser.nextText());
}
}
}
break;
}
case XmlPullParser.END_TAG: {//元素結(jié)尾標(biāo)識(shí)
//判斷是否為一個(gè)數(shù)據(jù)項(xiàng)的結(jié)束,如果是,將該數(shù)據(jù)項(xiàng)的數(shù)據(jù)添加到數(shù)據(jù)集contents中
if(parser.getName().equals(nodeName)&&map!=null){
contents.add(map);
map=null;
}
break;
}
}
}
return contents;
}
/**
* 將給定的數(shù)據(jù)集寫(xiě)入XML文件
* @param fileName: 根元素名,默認(rèn)設(shè)為跟文件名相同,如"peopleinfo"
* @param nodeName: 數(shù)據(jù)項(xiàng)名 如"people"
* @param attr: 數(shù)據(jù)項(xiàng)的屬性 如id,name,age,height
* @param con: 待寫(xiě)入的數(shù)據(jù)集
* @throws XmlPullParserException
* @throws IOException
*/
public void xmlWrite(String fileName,String nodeName,String[] attr,ArrayList<Map<String,Object>> con) throws XmlPullParserException, IOException{
serializer.startDocument("UTF-8", true);
serializer.startTag(null, fileName);//開(kāi)始根元素標(biāo)簽<peopleinfo>
for(int i=0;i<con.size();i++)
{
//開(kāi)始元素標(biāo)簽<people>
serializer.startTag(null, nodeName);
//標(biāo)簽people屬性
serializer.attribute(null, "tag", "people"+i);
//循環(huán)將子節(jié)點(diǎn)寫(xiě)入元素id,name,age,height
for(int j=0;j<attr.length;j++)
{
serializer.startTag(null, attr[j]);
serializer.text(con.get(i).get(attr[j]).toString());
serializer.endTag(null, attr[j]);
}
//結(jié)束標(biāo)簽</people>
serializer.endTag(null, nodeName);
}
//結(jié)束標(biāo)簽</peopleinfo>
serializer.endTag(null, fileName);
//結(jié)束文檔標(biāo)記
serializer.endDocument();
}
}
1. 使用該工具類(lèi)XmlPullHelper具體實(shí)現(xiàn)
//定義數(shù)據(jù)集對(duì)象contents用于保存從XML文件中讀取的數(shù)據(jù)
ArrayList<Map<String, Object>> contents = null;
//將數(shù)據(jù)寫(xiě)入XML文件,并保存到SD卡中
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//獲取SDCard目錄
File saveFile = new File(sdCardDir, "peopleinfo.xml");
FileWriter w=new FileWriter(saveFile);
XmlSerializer serializer = Xml.newSerializer();
XmlPullHelper xHelper=new XmlPullHelper(null,serializer);
//待寫(xiě)入的子元素標(biāo)簽
String []items={"id","name","age","height"};
//將Writer對(duì)象傳遞給 serializer
serializer.setOutput(w);
xHelper.xmlWrite("peopleinfo", "people", items, contents);//調(diào)用寫(xiě)入方法
w.flush(); //將serializer中數(shù)據(jù)寫(xiě)入文件
w.close();
}
//讀XML文件,解析并保存在數(shù)據(jù)集contents
XmlPullParser parser = getResources().getXml(R.xml.peopleinfo);
XmlPullHelper xHelper=new XmlPullHelper(parser,null);
String []items={"id","name","age","height"};
try{
contents=xHelper.xmlPull("people", items);//調(diào)用解析方法
}
catch(Exception e){
Log.e("XmlPullParser",e.getMessage(),e);
}
Android SDK內(nèi)置了Pull解釋器,使用XmlPullParser比較方便,解析XML文件的技術(shù)還有很多種,如 SAX和DOM,還需要更多的學(xué)習(xí)。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Android操作XML數(shù)據(jù)技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android資源操作技巧匯總》、《Android文件操作技巧匯總》、《Android操作SQLite數(shù)據(jù)庫(kù)技巧總結(jié)》、《Android操作json格式數(shù)據(jù)技巧總結(jié)》、《Android數(shù)據(jù)庫(kù)操作技巧總結(jié)》、《Android編程開(kāi)發(fā)之SD卡操作方法匯總》、《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android視圖View技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android實(shí)現(xiàn)滑動(dòng)到頂部懸停的效果
這篇文章給大家介紹一種不常見(jiàn)的實(shí)現(xiàn)Android滑動(dòng)到頂部懸停效果的方式,對(duì)大家開(kāi)發(fā)Android具有一定的參考借鑒價(jià)值,有需要的朋友們可以來(lái)一起看看。2016-09-09
Android Universal ImageLoader 緩存圖片
Universal Image Loader for Android的目的是為了實(shí)現(xiàn)異步的網(wǎng)絡(luò)圖片加載、緩存及顯示,支持多線(xiàn)程異步加載,通過(guò)本文給大家介紹Android Universal ImageLoader緩存圖片相關(guān)資料,涉及到imageloader緩存圖片相關(guān)知識(shí),對(duì)imageloader緩存圖片相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)2016-01-01
Android listview數(shù)據(jù)顯示及提示信息的實(shí)例
這篇文章主要介紹了Android listview數(shù)據(jù)顯示及提示信息的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05
android截圖事件監(jiān)聽(tīng)的原理與實(shí)現(xiàn)
本篇文章主要介紹了android截圖事件監(jiān)聽(tīng)的原理與實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
Android使用Item Swipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能
大家都用過(guò)QQ,肯定有人好奇QQ滑動(dòng)刪除Item的效果是怎樣實(shí)現(xiàn)的,其實(shí)我們使用Swipemenulistview就可以簡(jiǎn)單的實(shí)現(xiàn)。這篇文章主要介紹了Android使用ItemSwipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能,需要的朋友可以參考下2017-02-02
Android自定義指示器時(shí)間軸效果實(shí)例代碼詳解
指示器時(shí)間軸在外賣(mài)、購(gòu)物類(lèi)的APP里會(huì)經(jīng)常用到,效果大家都知道的差不多吧,下面小編通過(guò)實(shí)例代碼給大家分享Android自定義指示器時(shí)間軸效果,需要的朋友參考下吧2017-12-12
Android ListView 和ScroolView 出現(xiàn)onmeasure空指針的解決辦法
這篇文章主要介紹了Android ListView 和ScroolView 出現(xiàn)onmeasure空指針的解決辦法的相關(guān)資料,需要的朋友可以參考下2017-02-02
android開(kāi)發(fā)教程之系統(tǒng)資源的使用方法 android資源文件
這篇文章主要介紹了android中的系統(tǒng)資源的使用方法,包括顏色資源 、字符串資源、尺寸資源、XML資源文件,需要的朋友可以參考下2014-02-02
Jetpack?Compose?DropdownMenu手指跟隨點(diǎn)擊顯示
這篇文章主要為大家介紹了Jetpack?Compose?DropdownMenu手指跟隨點(diǎn)擊位置顯示實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11

