前几天,公司内部的通讯APP定下了服务器下发的数据全是在XML文件里面,经过研究发现还是pull解析XML文件比较方便,故此贴上XML文件解析流程。
首先,我们得拿到XML文件,代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<ContactsResponse>
<status>success</status>
<date>2015-07-20</date>
<results>
<currentClass>研发部</currentClass>
<persons>
<person id="1">
<name>张AA</name>
<cellphone>137-0047-AAA</cellphone>
<qq>345108AAA</qq>
<email>34510AAA0@AAq.com</email>
</person>
<person id="2">
<name>陈AA</name>
<cellphone>138-2346-AAA</cellphone>
<qq>147853AAA</qq>
<email>cxz@baodAAg.cn</email>
</person>
<person id="3">
<name>赵AA</name>
<cellphone>188-8955-AAA</cellphone>
<qq>82189AAA</qq>
<email>82189AAA@AA.com</email>
</person>
<person id="4">
<name>吉AA</name>
<cellphone>176-0893-AAA</cellphone>
<qq>609800AAA</qq>
<email>qiushi@liAA.cn</email>
</person>
<person id="5">
<name>AAA</name>
<cellphone>180-8981-AAA</cellphone>
<qq>859107AAA</qq>
<email>859107AAA@AAA.com</email>
</person>
</persons>
</results>
</ContactsResponse>
前面的内容,我们可以选择性的忽视掉,后面我们发现主要数据是存在persons这个大标签里面的person这个小标签内。而且我的XML文件存放的位置为:assets这个文件夹里面。根据对XML文件的分析,不难看出,我们的数据有:id、name、cellphone、qq、email,这几个,所以先写一个person的实体类,里面添加对应的变量,并添加get、set方法,代码如下:
package com.xfdykt.xmltest;
public class Person {
private String id;
private String name;
private String cellphone;
private String qq;
private String email;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
实体类构造完成,那么我们的数据相应的就应该存入进去。但是我怎么把多个同种类型的数据存进去呢,一般大家都要想到:
1、数据不是定长的,所以数组不可达到快速的存取,所以要用集合
2、既然数据是使用的集合,那么考虑到以前刚学习编程的时候用到的数组对象,那么我们这里就应该使用泛型对象。
3、既然使用了泛型对象了,那么我们要取出数据,是不是对应的直接使用一个泛型对象就能简单省事呢?
4、最重要的是,安卓中数据传输中有几个重要的东西是:intent、context、message等等。但是这里我们如何简单快捷的把我们要的文件传输过去呢?我采用的是上下文(context)传递文件名,在解析xml文件的时候设定路径。
5、获取到XML文件后,我们要打开一个文件,常规的:读入流→设定文件编码→相应的操作
所以按照上面的思路,我们解析XML的代码如下:
public class Snippet {
public List<Person> parse(Context context, String xmlPath) {
List<Person> persons = new ArrayList<Person>();
Person person = null;
InputStream inputStream = null;
// 获得XmlPullParser解析器
XmlPullParser xmlParser = Xml.newPullParser();
try {
// 得到文件流,并设置编码方式
inputStream = context.getResources().getAssets().open(xmlPath);
xmlParser.setInput(inputStream, "utf-8");
// 获得解析到的事件类别,这里有开始文档,结束文档,开始标签,结束标签,文本等等事件。
int evtType = xmlParser.getEventType();
// 一直循环,直到文档结束
while (evtType != XmlPullParser.END_DOCUMENT) {
switch (evtType) {
case XmlPullParser.START_TAG:
String tag = xmlParser.getName();
// 如果是person标签开始,则说明需要实例化对象了
if (tag.equalsIgnoreCase("person")) {
person = new Person();
// 取出person标签中的一些属性值
person.setId(xmlParser.getAttributeValue(null, "id"));
} else if (person != null) {
// 如果遇到name标签,则读取它内容
if (tag.equalsIgnoreCase("name")) {
person.setName(xmlParser.nextText());
// 如果遇到cellphone标签,则读取它内容
} else if (tag.equalsIgnoreCase("cellphone")) {
person.setCellphone(xmlParser.nextText());
// 如果遇到qq标签,则读取它内容
} else if (tag.equalsIgnoreCase("qq")) {
person.setQq(xmlParser.nextText());
// 如果遇到email标签,则读取它内容
} else if (tag.equalsIgnoreCase("email")) {
person.setEmail(xmlParser.nextText());
}
}
break;
case XmlPullParser.END_TAG:
// 如果遇到person标签结束,则把person对象添加进集合中
if (xmlParser.getName().equalsIgnoreCase("person")
&& person != null) {
persons.add(person);
person = null;
}
break;
default:
break;
}
// 如果xml没有结束,则导航到下一个person节点
evtType = xmlParser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return persons;
}
}
上面代码中已经把一些东西讲解的明白了,所以不再解释。当我们的文件解析完成数据需要传出来的时候,我们不放用一个事件来控制,为了简单方便,我就直接再一个按钮事件里写一个遍历,在log里面输出数据了,代码如下:
Snippet snippet = new Snippet();
List<Person> contacts= snippet.parse(getApplicationContext(), "Contacts.xml");
for (int i = 0; i < contacts.size(); i++) {
System.err.println(contacts.get(i).getName()+"::"+contacts.get(i).getCellphone());
}
上面的输出,只是一小部分,当然要全部输出出来,我们只需加上对应的get方法就可以了。
时间仓促,不足之处往见谅。