Android学习系列: 采用pull解析xml文件

        一般我们是与服务器进行通信,服务器返回指定的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);

运行后得到的结果如下:



详细代码请看:https://github.com/NancyLin/XmlPullParser

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值