xml文件的解析方式有很多种,在Android中我们这里使用pull解析的方式来解析xml文件
首先拿到一个xml文件,这里可以自建一个,文件名”weather.xml”,内容如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<weather>
<city>
<name>上海</name>
<temp>7°</temp>
<pm>80</pm>
</city>
<city>
<name>北京</name>
<temp>-3°</temp>
<pm>80</pm>
</city>
<city>
<name>广州</name>
<temp>19°</temp>
<pm>60</pm>
</city>
</weather>
把这个xml文件放到src文件夹下
//获取到src文件夹下的资源文件
InputStream is = getClassLoader().getResourceAsStream("weather.xml");
//拿到pull解析对象
XmlPullParser xp = Xml.newPullParser();
try {
//初始化,告诉它xml文件在哪里
xp.setInput(is, "utf-8");
//获取当前事件的事件类型(建立一个指针),即判断当前得到的是一个什么样的结点,继而知道我们应该进行什么样的操作
//例如解析到头结点做什么操作,解析到开始结点做什么操作,解析到结束结点做什么样的操作
int type = xp.getEventType();
} catch (Exception e) {
e.printStackTrace();
}
- 事件类型主要有五种
- START_DOCUMENT:xml头的事件类型(type=0)
- END_DOCUMENT:xml尾的事件类型(type=1)
- START_TAG:开始节点的事件类型(type=2)
- END_TAG:结束节点的事件类型(type=3)
- TEXT:文本节点的事件类型(type=4)
while(type != XmlPullParser.END_DOCUMENT){ //如果解析没结束就继续解析
//根据节点的类型,要做不同的操作
switch(type){
case XmlPullParser.START_TAG:
//开始结点有很多个,需要精确判断
if("weather".equals(xp.getName())){ //获取当前结点的名字
}
else if("city".equals(xp.getName())){
//创建city的javabean对象
}
}
//把指针移动到下一个结点,并返回该结点的事件类型
type = xp.next();
}
当解析到city的开始节点时,创建city对象,将city里的各个属性封装,创建对象是为了更方便的保存即将解析到的文本
public class City {
private String name;
private String temp;
private String pm;
.
.
.
//构造,get/set方法
然后在city的开始结点处创建City对象,注:City放到while外面初始化,为了防止它出了if里那一块就会消失.
而且City在整个过程中都要用,因此要给它设置一个全局引用
List<City> citylList;
这个全局引用可以在解析到weather结点的时候把它new出来,因为当解析到weather结点时,下一个就会解析city结点,即
if("weather".equals(xp.getName())){ //获取当前结点的名字
//创建city集合对象,用于存放city的javabean对象
citylList = new ArrayList<City>();
}
开始结点的所有解析:
case XmlPullParser.START_TAG:
//开始结点有很多个,需要精确判断
if("weather".equals(xp.getName())){ //获取当前结点的名字
//创建city集合对象,用于存放city的javabean对象
citylList = new ArrayList<City>();
}
else if("city".equals(xp.getName())){
//创建city的javabean对象
city = new City();
}
else if("name".equals(xp.getName())){
//当解析到name的时候,它的下一个就是name里的内容
//获取当前结点的下一个结点的文本,,并把指针移动到当前结点的结束结点
String name = xp.nextText();
city.setName(name);
}
else if("temp".equals(xp.getName())){
String temp = xp.nextText();
city.setTemp(temp);
}
else if("pm".equals(xp.getName())){
String pm = xp.nextText();
city.setPm(pm);
}
break;
结束结点解析:
//结束结点name,temp,pm都什么都不用干,只有解析到city结点时才会有事情做
case XmlPullParser.END_TAG:
if("city".equals(xp.getName())){
//把city的javabean放到集合中
citylList.add(city);
}
break;
最后测试一下结果,在City对象中重写toString方法,然后把xml文件中的成员信息输出打印出来
//测试,把xml文件中的成员信息都打印出来
for (City c: citylList) {
System.out.println(c.toString());
}
所得结果:
注意:
xml文件所保存的编码方式,是utf-8,还是其它,与程序中的xp.setInput(is, "utf-8")
统一起来,如果不一致的话就会乱码
全部代码:
package com.gigi.pullparser;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.gigi.pullparser.domain.City;
import android.os.Bundle;
import android.app.Activity;
import android.util.Xml;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
List<City> citylList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
//获取到src文件夹下的资源文件
InputStream is = getClassLoader().getResourceAsStream("weather.xml");
//拿到pull解析对象
XmlPullParser xp = Xml.newPullParser();
try {
//初始化,告诉它xml文件在哪里
xp.setInput(is, "utf-8");
//获取当前事件的事件类型(建立一个指针),即判断当前得到的是一个什么样的结点,继而知道我们应该进行什么样的操作
//例如解析到头结点做什么操作,解析到开始结点做什么操作,解析到结束结点做什么样的操作
int type = xp.getEventType();
City city = null;
while(type != XmlPullParser.END_DOCUMENT){ //如果解析没结束就继续解析
//根据节点的类型,要做不同的操作
switch(type){
case XmlPullParser.START_TAG:
//开始结点有很多个,需要精确判断
if("weather".equals(xp.getName())){ //获取当前结点的名字
//创建city集合对象,用于存放city的javabean对象
citylList = new ArrayList<City>();
}
else if("city".equals(xp.getName())){
//创建city的javabean对象
city = new City();
}
else if("name".equals(xp.getName())){
//当解析到name的时候,它的下一个就是name里的内容
//获取当前结点的下一个结点的文本,,并把指针移动到当前结点的结束结点
String name = xp.nextText();
city.setName(name);
}
else if("temp".equals(xp.getName())){
String temp = xp.nextText();
city.setTemp(temp);
}
else if("pm".equals(xp.getName())){
String pm = xp.nextText();
city.setPm(pm);
}
break;
//结束结点name,temp,pm都什么都不用干,只有解析到city结点时才会有事情做
case XmlPullParser.END_TAG:
if("city".equals(xp.getName())){
//把city的javabean放到集合中
citylList.add(city);
}
break;
}
//把指针移动到下一个结点,并返回该结点的事件类型
type = xp.next();
}
//测试,把xml文件中的成员信息都打印出来
for (City c: citylList) {
System.out.println(c.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}