XML技术在跨平台的情况下的数据交互中得到了广泛的应用,假如我们需要开发一个Android应用程序,需要同服务器端进行数据交互,通过XML文件可以很方便的在Android平台和服务器之间进行数据传输,具体实现涉及到对XML文件进行解析及写入的技术。本文实现在Android平台上基于Pull方式对XML文件解析的技术。
XmlPullParser是一个java实现的开源API包(源码下载地址http://www.xmlpull.org/
),实现了pull方式解析xml文件的方法,Android SDK中包含了该API,使用时需要导入以下三个包:
importorg.xmlpull.v1.XmlPullParser;//包含解析XML文件类的包
importorg.xmlpull.v1.XmlPullParserException;//处理异常
importorg.xmlpull.v1.XmlSerializer;//包含写入XML文件类的包
我们以SQLite数据库课堂练习中的数据类People为例,People类有4个属性:ID,Name,Age,Height,假设有一条测试数据ID=1,Name=”杜甫”,Age=30,Height=1.75,
在XML文件中对应的数据项元素如下:
<peopleinfo>
<peopletag="item1">
<id>1</id>
<name>杜甫</name>
<age>30</age>
<height>1.75</height>
</people>
</peopleinfo>
1.使用XmlPullParser对该文件解析
首先需要初始化一个XmlPullParser对象parser,R.xml.peopleinfo为文件peopleinfo.xml在项目中的标识,读入该文件后一步一步对文件中的元素进行解析。
XmlPullParserparser= getResources().getXml(R.xml.peopleinfo);
XmlPullParser的相关函数及说明如下:
相关函数或变量 | 说明 | 示例 |
XmlPullParser.START_DOCUMENT | 文档开始标识,根元素 | <peopleinfo> |
XmlPullParser.END_DOCUMENT | 文档结束标识 | </peopleinfo> |
XmlPullParser.START_TAG | 元素开始标识 | <people> |
XmlPullParser.END_TAG | 元素结束标识 | </people> |
getEventType() | 获取当元素的类型(如START_TAG, END_TAG, TEXT, etc.) | 如<peopleinfo> 的类型为START_DOCUMENT |
next() | 获取下一个待解析元素 | 事件表示<>括号中的一个项 |
getName() | 获取当前元素的名字 | 如读取到<age>,返回值为”age” |
nextText() | 返回当前元素所对应的文本值 | 如事件为<height>时,返回1.75 |
getAttributeName(int index) | 获取当前元素中属性名 | 如tag |
getAttributeValue(int index) | 获取当前元素中属性的值 | 如"item1" |
解析步骤:
1)初始化parser,指定xml文件
2)读取文档开始标识,根元素<peopleinfo>
3)读取数据项元素开始标识, <people>
a)读取数据项元素的属性,tag="item1"
b)读取数据项的子元素,id,name,age,height
4)一个数据项结束,</people>,保存该数据项的结果
5)读取文档结束标识,</peopleinfo>
2.使用XmlSerializer对写XML文件
写入XML文件的过程:先初始化一个XmlSerializer对象serializer,设置输出的Writer对象,然后数据写入serializer中,再将该对象通过Writer写入文件。
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(writer);
//…
writer.flush()
XmlSerializer的相关函数及说明如下:
相关函数 | 说明 | 示例 |
setOutput(Writerwriter) | 设置输出的Writer对象 |
|
startDocument(Stringencoding,Booleanstandalone); | 写入XML文件的起始标识语句,必须在setOutput后被调用 | <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
startTag(Stringnamespace,Stringname); | 写入开始元素标识 | 如<people>,<age> |
attribute(Stringnamespace,Stringname,Stringvalue); |
| 如tag=”people1” |
text(Stringtext) | 写入元素值 | 如:杜甫 |
endTag(Stringnamespace,Stringname) | 写入元素结束标识 | 如</people>,</age> |
endDocument(); | 写入文档结束标记 |
|
写入步骤:
1)初始化serializer
2)设置Writer对象writer
3) 写入文档开始标记<?xml version="1.0" encoding="UTF-8"standalone="yes" ?>
4) 写入根元素<peopleinfo>
5)写入数据项元素<people>
a)写入数据项属性tag=”people1”
b)写入数据项子元素,id,name,age,height
6) 写入数据项元素结束符</people>
7) 写入根元素结束符</peopleinfo>
8)写入文档结束符
9)通过writer将数据写入文件,writer.flush()
10)关闭writer对象
实现工具类XmlPullHelper,提供对XML文件解析和写入的
1.具体实现,代码如下:
- packageaaron.android.SQLiteDamon;
- importjava.io.IOException;
- importjava.io.Writer;
- importjava.util.ArrayList;
- importjava.util.HashMap;
- importjava.util.Map;
- importorg.xmlpull.v1.XmlPullParser;
- importorg.xmlpull.v1.XmlPullParserException;
- importorg.xmlpull.v1.XmlSerializer;
- importandroid.util.Log;
- publicclassXmlPullHelper{
- privateXmlPullParserparser;
- privateXmlSerializerserializer;
- privateArrayList<Map<String,Object>>contents=newArrayList<Map<String,Object>>();
- privateMap<String,Object>map=null;
- publicXmlPullHelper(XmlPullParserparser,XmlSerializerserial){
- this.parser=parser;
- this.serializer=serial;
- }
- /**
- *将xml文件中的所有节点的数据解析后保存在一个ArrayList中返回
- *@paramnodeName:数据项的名称,这里为"people"
- *@paramattr:数据项的属性,如id,name,age,height
- *@return解析该xml文件数据的结果
- *@throwsXmlPullParserException
- *@throwsIOException
- */
- publicArrayList<Map<String,Object>>xmlPull(StringnodeName,String[]attr)throwsXmlPullParserException,IOException{
- //循环读取所有的元素
- while(parser.next()!=XmlPullParser.END_DOCUMENT){
- switch(parser.getEventType()){
- caseXmlPullParser.START_DOCUMENT:
- break;
- caseXmlPullParser.START_TAG:{//元素开始标识
- //判断是否为所需要的数据项,如果是,在初始化一个map用于保存该数据项的值
- if(parser.getName()!=null&&parser.getName().equals(nodeName)){
- map=newHashMap<String,Object>();
- //循环读取该元素中所有的属性
- for(intj=0;j<parser.getAttributeCount();j++)
- map.put(parser.getAttributeName(j),parser.getAttributeValue(j));//添加属性的值,如tag="item1"
- }
- elseif(map!=null){
- for(inti=0;i<attr.length;i++){
- if(parser.getName()!=null&&parser.getName().equals(attr[i])){//添加子元素的值,如<name>张三</name>
- map.put(attr[i],parser.nextText());
- }
- }
- }
- break;
- }
- caseXmlPullParser.END_TAG:{//元素结尾标识
- //判断是否为一个数据项的结束,如果是,将该数据项的数据添加到数据集contents中
- if(parser.getName().equals(nodeName)&&map!=null){
- contents.add(map);
- map=null;
- }
- break;
- }
- }
- }
- returncontents;
- }
- /**
- *将给定的数据集写入XML文件
- *@paramfileName:根元素名,默认设为跟文件名相同,如"peopleinfo"
- *@paramnodeName:数据项名如"people"
- *@paramattr:数据项的属性如id,name,age,height
- *@paramcon:待写入的数据集
- *@throwsXmlPullParserException
- *@throwsIOException
- */
- publicvoidxmlWrite(StringfileName,StringnodeName,String[]attr,ArrayList<Map<String,Object>>con)throwsXmlPullParserException,IOException{
- serializer.startDocument("UTF-8",true);
- serializer.startTag(null,fileName);//开始根元素标签<peopleinfo>
- for(inti=0;i<con.size();i++)
- {
- //开始元素标签<people>
- serializer.startTag(null,nodeName);
- //标签people属性
- serializer.attribute(null,"tag","people"+i);
- //循环将子节点写入元素id,name,age,height
- for(intj=0;j<attr.length;j++)
- {
- serializer.startTag(null,attr[j]);
- serializer.text(con.get(i).get(attr[j]).toString());
- serializer.endTag(null,attr[j]);
- }
- //结束标签</people>
- serializer.endTag(null,nodeName);
- }
- //结束标签</peopleinfo>
- serializer.endTag(null,fileName);
- //结束文档标记
- serializer.endDocument();
- }
- }
1.使用该工具类XmlPullHelper具体实现
- //定义数据集对象contents用于保存从XML文件中读取的数据
- ArrayList<Map<String,Object>>contents=null;
- //将数据写入XML文件,并保存到SD卡中
- if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
- FilesdCardDir=Environment.getExternalStorageDirectory();//获取SDCard目录
- FilesaveFile=newFile(sdCardDir,"peopleinfo.xml");
- FileWriterw=newFileWriter(saveFile);
- XmlSerializerserializer=Xml.newSerializer();
- XmlPullHelperxHelper=newXmlPullHelper(null,serializer);
- //待写入的子元素标签
- String[]items={"id","name","age","height"};
- //将Writer对象传递给serializer
- serializer.setOutput(w);
- xHelper.xmlWrite("peopleinfo","people",items,contents);//调用写入方法
- w.flush();//将serializer中数据写入文件
- w.close();
- }
- //读XML文件,解析并保存在数据集contents
- XmlPullParserparser=getResources().getXml(R.xml.peopleinfo);
- XmlPullHelperxHelper=newXmlPullHelper(parser,null);
- String[]items={"id","name","age","height"};
- try{
- contents=xHelper.xmlPull("people",items);//调用解析方法
- }
- catch(Exceptione){
- Log.e("XmlPullParser",e.getMessage(),e);
- }