Android提供了好几种解析XML的方式,今天学习Pull解析方式:
DOM解析:需要加载进内存,效率较低,占用资源;
SAX解析:基于事件驱动
Pull解析:也是基于事件的解析,但是比SAX解析方式简单,方便;
这里假设我们要解析weather.xml文档
<?xml version="1.0" encoding="utf-8"?> <infos> <city id="1"> <temp>20摄氏度</temp> <weather>5月20日 多云转阴</weather> <wind>南风3-4级</wind> <name>上海</name> <pm>200</pm> </city> <city id="2"> <temp>20摄氏度</temp> <weather>5月20日 多云转阴</weather> <wind>南风5-4级</wind> <name>北京</name> <pm>800</pm> </city> <city id="3"> <temp>20摄氏度</temp> <weather>5月20日 多云转阴</weather> <wind>南风1-4级</wind> <name>哈尔滨</name> <pm>100</pm> </city> </infos>weather.xml定义了每个城市的天气情况,我们通过pull解析的方式来解析这个xml文件,下面是天气的业务类WeatherInfos:
package com.hm.weather.service; public class WeatherInfos { private int id; private String name; private String wind; private String temp; private String weather; private String pm; @Override public String toString() { return "[城市id=" + id + ", 名称=" + name + ", 风力=" + wind + ", 温度=" + temp + ", 天气=" + weather + ", pm2.5=" + pm + "]"; } public String getWeather() { return weather; } public void setWeather(String weather) { this.weather = weather; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWind() { return wind; } public void setWind(String wind) { this.wind = wind; } public String getTemp() { return temp; } public void setTemp(String temp) { this.temp = temp; } public String getPm() { return pm; } public void setPm(String pm) { this.pm = pm; } }WeatherInfos业务类定义了每个城市的温度、PM2.5、风力、天气情况。
下面是我们整个app的基本类,MainActivity:
package com.hm.weather; import java.util.List; import org.xmlpull.v1.XmlPullParser; import com.hm.weather.service.WeatherInfos; import weatherService.WeatherService; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.util.Xml; import android.view.Menu; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView tv_weather; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_weather = (TextView) findViewById(R.id.tv_weather); XmlPullParser xmlPullParser = Xml.newPullParser(); try { List<WeatherInfos> weatherinfos = WeatherService.getWeatherInfos(MainActivity.this.getClassLoader().getResourceAsStream("weather.xml")); StringBuffer sb = new StringBuffer(); for(WeatherInfos info:weatherinfos){ String str = info.toString(); Log.i("hm", str); sb.append(str); tv_weather.setText(sb); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Toast.makeText(this, "解析失败", Toast.LENGTH_SHORT).show(); } } }里面我们使用了WeatherService.getWeatherInfos(MainActivity.this.getClassLoader().getResourceAsStream("weather.xml"))去解析weather.xml文件,获得各个城市的天气情况,并且显示到界面的TextView上。我们的布局文件如下,只有一个简单的TextView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/tv_weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="" /> </RelativeLayout>接下来,我们看看最主要的,也就是如何解析xml文件的,我们抽取除了一个Service类,
package weatherService; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import com.hm.weather.service.WeatherInfos; import android.R.xml; import android.util.Log; import android.util.Xml; public class WeatherService { public static List<WeatherInfos> getWeatherInfos(InputStream is) throws Exception{ XmlPullParser xmlPullParser = Xml.newPullParser(); //初始化解析器 xmlPullParser.setInput(is, "utf-8"); List<WeatherInfos> infos = null; WeatherInfos weatherInfo = null; int type = xmlPullParser.getEventType();//得到当前事件的类型 Log.i("hm", type+""); while(type != XmlPullParser.END_DOCUMENT){//只要type不是xml文件的结尾,我们就一直循环解析 switch (type) { case XmlPullParser.START_TAG://每个标签头 if("infos".equals(xmlPullParser.getName())){//如表标签头是infos字样 infos = new ArrayList<WeatherInfos>(); }else if("city".equals(xmlPullParser.getName())){ weatherInfo = new WeatherInfos(); String id = xmlPullParser.getAttributeValue(0);//获得city标签的属性,因为我们只有一个id属性,所以参数为0 weatherInfo.setId(Integer.parseInt(id)); }else if("temp".equals(xmlPullParser.getName())){ String temp = xmlPullParser.nextText();//nextText是获得标签里的信息 weatherInfo.setTemp(temp); }else if("weather".equals(xmlPullParser.getName())){ String weather = xmlPullParser.nextText(); weatherInfo.setWeather(weather); }else if("wind".equals(xmlPullParser.getName())){ String wind = xmlPullParser.nextText(); weatherInfo.setWind(wind); }else if("name".equals(xmlPullParser.getName())){ String name = xmlPullParser.nextText(); weatherInfo.setName(name); }else if("pm".equals(xmlPullParser.getName())){ String pm = xmlPullParser.nextText(); weatherInfo.setPm(pm); } break; case XmlPullParser.END_TAG://每个标签的结尾 if("city".equals(xmlPullParser.getName())){//如果标签尾是city表示一个城市信息解析完毕,我们把它加入我们的list集合 infos.add(weatherInfo); weatherInfo = null; } break; } type = xmlPullParser.next();//解析完一个字样,指向下一个 } return infos; } }这个解析的过程,类似一个游标一样,指向一个,然后解析获取数据存储,解析完指向下一个需要解析的字样。如果解析完毕,就返回存储的信息。