一般我们是与服务器进行通信,服务器返回指定的xml信息,通过解析xml得到我们需要的数据。为了简单,我们不与服务器通信,而是直接写好XML文件,学习如何在Android下解析XML文件。
我们先创建好Android项目,在“src”目录中新建文件“weather.xml”,该文件包含了多个城市的天气状况信息,具体代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<infos>
<city id="1">
<temp>20.C / 30.C</temp>
<weather>5月20日 多云转阴</weather>
<wind>南风3-4级</wind>
<name>上海</name>
<pm>200</pm>
</city>
<city id="2">
<temp>26.C / 30.C</temp>
<weather>5月20日 多云转阴</weather>
<wind>南风7-8级</wind>
<name>北京</name>
<pm>800</pm>
</city>
<city id="3">
<temp>6.C / 10.C</temp>
<weather>5月20日 多云转阴</weather>
<wind>南风7-8级</wind>
<name>哈尔滨</name>
<pm>100</pm>
</city>
</infos>
接着,我们定义一个天气类,在“com.nancy.domain”包中创建一个天气类WeatherInfo,包含天气状况等属性。
public class WeatherInfo {
private int id; //城市id
private String temp; //温度
private String weather; //天气
private String wind; //风向
private String name; //名称
private String pm; //pm2.5
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getWeather() {
return weather;
}
public void setWeather(String weather) {
this.weather = weather;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPm() {
return pm;
}
public void setPm(String pm) {
this.pm = pm;
}
}
xml的解析有以下几种:
(1)DOM解析,需要把XML文件一次性加载到内存中,生成一个树状结构,在内存里对树状结构进行修改或者添加节点。缺点是消耗内存比较大,如果XML文件比较大,不建议采用DOM解析。
(2)SAX解析。基于事件的方式来解析,每产生一个事件,就会去获取数据,但是事件自上而下的,如果事件过去了,就不能再回去。这种方法速度快,效率高,但是不能回退。
(3)在Android下,有Pull解析,与SAX解析类似,也是基于事件方式,语法较为简单,也容易理解。
下面,我们就用Pull解析来进行xml的解析。首先我们在“com.nancy.weather.service”包中创建一个解析类WeatherService。
在该类中,我们定义一个解析天气xml文件的方法 getWeatherInfos( InputStream is ),返回天气类 WeatherInfos的泛型List 。并在该方法中使用XmlPullParser来解析。
当解析器初始化setInput后,则定义了一个指向文件开头的指针,通过getEventType得到当前的事件类型,我们可以在XmlPullParser的源代码中查看事件的几种类型,其中包括“START_DOCUMENT”,"END_DOCUMENT","START_TAG","END_TAG"等。我们根据循环获取的EventType,直到“END_DOCUMENT”
具体代码如下:
import android.util.Xml;
import com.nancy.weather.domain.WeatherInfo;
import org.xmlpull.v1.XmlPullParser;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by nancy on 15-10-10.
*/
public class WeatherService {
public static List<WeatherInfo> getWeatherInfos( InputStream is ){
List<WeatherInfo> weatherInfos = null;
WeatherInfo weatherInfo = null;
//创建xml pull解析器
XmlPullParser parser = Xml.newPullParser();
try{
//初始化pull xml解析
parser.setInput(is, "utf-8");
int type = parser.getEventType();
while( type != XmlPullParser.END_DOCUMENT){
switch( type ){
case XmlPullParser.START_TAG:
if( "infos".equals( parser.getName() ) ){
weatherInfos = new ArrayList<WeatherInfo>();
}else if( "city".equals(parser.getName()) ){
weatherInfo = new WeatherInfo();
weatherInfo.setId( Integer.parseInt(parser.getAttributeValue(0)) );
}else if("temp".equals(parser.getName())){
weatherInfo.setTemp( parser.nextText() );
}else if("weather".equals(parser.getName())){
weatherInfo.setWeather(parser.nextText());
}else if("wind".equals(parser.getName())){
weatherInfo.setWind(parser.nextText());
}else if("name".equals(parser.getName())){
weatherInfo.setName(parser.nextText());
}else if("pm".equals(parser.getName())){
weatherInfo.setPm(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if("city".equals(parser.getName())){
weatherInfos.add(weatherInfo);
weatherInfo = null;
}
break;
}
type = parser.next();
}
}catch(Exception e){
e.printStackTrace();
}
return weatherInfos;
}
}
接下来,我们在界面中将天气信息显示出来。
在main.xml中定义一个TextView
<TextView
android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
重写天气类 WeatherInfo 中的toString函数,将城市的天气信息返回字符串
@Override
public String toString() {
return name+"天气信息{" +
"id=" + id +
", 气温='" + temp + '\'' +
", 天气='" + weather + '\'' +
", 风向='" + wind + '\'' +
", name='" + name + '\'' +
", pm2.5='" + pm + '\'' +
'}';
}
在MainActivity.java的onCreate方法中,使用类加载器加载 weather.xml文件,使用WeatherService的getWeatherInfos方法,将各个城市的天气情况解析出来。
TextView tvText = (TextView) this.findViewById(R.id.tv);
//使用类加载器加载xml文件
List<WeatherInfo> weatherInfos = WeatherService.getWeatherInfos(MainActivity.class.getClassLoader()
.getResourceAsStream("weather.xml"));
String showWeatherStr = "";
for(WeatherInfo info: weatherInfos){
showWeatherStr += info.toString() + "\n";
}
tvText.setText(showWeatherStr);
运行后得到的结果如下: