Android中,XML文件的解析

源码下载地址:Android中,使用SAX和PULL解析天气预报XML

天气预报是大家日常生活中经常接触到的信息,现在有一天气预报信息,对其进行解析。

在Android中对XML的解析常用到两种解析技术:

SAX解析和PULL解析。

SAX支持已经内置到了JDK1.5中,无需在项目中添加任何jar文件。

Pull是Android内置的解析器(谷歌推荐使用Pull)

两种解析技术都是基于事件驱动的流式处理数据。

 

已经获取了某天的天气预报信息,数据如下:

weather.xml     为了读取方便,放在项目src目录下。

<?xml version="1.0" ?>
<xml_api_reply version="1">
	<weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1"
		row="0" section="0">
		<forecast_information>
			<city data="" />
			<postal_code data="" />
			<latitude_e6 data="34720001" />
			<longitude_e6 data="113650001" />
			<forecast_date data="2012-04-06" />
			<current_date_time data="2012-04-06 20:00:00 +0000" />
			<unit_system data="SI" />
		</forecast_information>
		<current_conditions>
			<condition data="晴" />
			<temp_f data="75" />
			<temp_c data="24" />
			<humidity data="湿度: 5%" />
			<icon data="/ig/images/weather/sunny.gif" />
			<wind_condition data="风向: 东南、风速:2 米/秒" />
		</current_conditions>
		<forecast_conditions>
			<day_of_week data="周五" />
			<low data="9" />
			<high data="24" />
			<icon data="/ig/images/weather/mostly_sunny.gif" />
			<condition data="晴间多云" />
		</forecast_conditions>
		<forecast_conditions>
			<day_of_week data="周六" />
			<low data="10" />
			<high data="25" />
			<icon data="/ig/images/weather/sunny.gif" />
			<condition data="晴" />
		</forecast_conditions>
		<forecast_conditions>
			<day_of_week data="周日" />
			<low data="12" />
			<high data="26" />
			<icon data="/ig/images/weather/mostly_sunny.gif" />
			<condition data="晴间多云" />
		</forecast_conditions>
		<forecast_conditions>
			<day_of_week data="周一" />
			<low data="12" />
			<high data="21" />
			<icon data="/ig/images/weather/mostly_sunny.gif" />
			<condition data="以晴为主" />
		</forecast_conditions>
	</weather>
</xml_api_reply>


CurrentWeatherInfo.java  存放当前天气情况的实体Bean

package com.feioh;

/**
 * 存放当前天气情况的实体Bean
 * 
 * @author yalin
 * 
 */
public class CurrentWeatherInfo {
	private String content;
	private String humidity;
	private String wind_condition;

	public CurrentWeatherInfo() {
		super();
	}

	public CurrentWeatherInfo(String content, String humidity,
			String wind_condition) {
		super();
		this.content = content;
		this.humidity = humidity;
		this.wind_condition = wind_condition;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getHumidity() {
		return humidity;
	}

	public void setHumidity(String humidity) {
		this.humidity = humidity;
	}

	public String getWind_condition() {
		return wind_condition;
	}

	public void setWind_condition(String wind_condition) {
		this.wind_condition = wind_condition;
	}

	// 重写toString(),更改实体返回信息
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "当前天气情况:"+content + "," + humidity +","+  wind_condition + "。";
	}

}

WeatherInfo.java  存放每天天气情况的实体Bean

package com.feioh;

/**
 * 存放每天天气信息的实体Bean
 * @author yalin
 *
 */
public class WeatherInfo {
	private String date;
	private String high;
	private String low;
	private String content;
	
	
	public WeatherInfo() {
		super();
	}
	
	public WeatherInfo(String date, String high, String low, String content) {
		super();
		this.date = date;
		this.high = high;
		this.low = low;
		this.content = content;
	}
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public String getHigh() {
		return high;
	}
	public void setHigh(String high) {
		this.high = high;
	}
	public String getLow() {
		return low;
	}
	public void setLow(String low) {
		this.low = low;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	
	//重写toString(),更改实体返回信息
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return date+",天气:"+content+",最高温度:"+high+"℃,最低温度:"+low+"℃。";
	}
	
	
}


WeatherService.java  使用SAX技术解析xml的业务类

package com.feioh;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * 解析XML所需要的业务类
 * 在这个业务类中,通过SAXParserFactory得到解析器saxParser
 * @author yalin
 *
 */
public class WeatherService {
	public static Map<String,Object> readXML(InputStream inputStream) throws Exception
	{
		//创建一个解析器工厂
		SAXParserFactory factory=SAXParserFactory.newInstance();
		//通过工厂创建解析器
		SAXParser saxParser=factory.newSAXParser();
		//实例saxParser.parse()函数 所需要的Handler对象
		XMLContentHandler handler=new XMLContentHandler();
		//开始解析...ing
		saxParser.parse(inputStream, handler);
		//关闭输入流
		inputStream.close();
		//得到每天天气情况信息
		List<WeatherInfo> re=handler.getList();
		//得到当前天气情况信息
		CurrentWeatherInfo currentWeatherInfo=handler.getCurrent();
		
		//把当前天气情况 和 每天天气情况放入到Map集合中
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("everyday", re);
		map.put("current", currentWeatherInfo);
		return map;
	}
}


XMLContentHandler.java  SAX解析所需要的Handler

package com.feioh;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * SAX技术是通过继承DefaultHandler实现对xml的解析的。 SAX读取xml时,只要提供实现ContentHandler接口的类
 * DefaultHandler实现了ContentHandler接口,继承这个类,重写相应方法即可。
 * 
 * @author yalin
 * 
 */
public class XMLContentHandler extends DefaultHandler {
	private List<WeatherInfo> list;// 存放解析过的xml数据集
	private WeatherInfo weatherInfo;// 存放解析过的xml数据对象
	private CurrentWeatherInfo currentWeatherInfo;// 存放解析过的当前天气信息数据
	boolean TAG = false;// 标识属于哪个标签的天气情况

	// 提供一个公共方法,便于其他使用者调用
	public List<WeatherInfo> getList() {
		return list;
	}
	//提供一个公共方法,返回当前天气情况
	public CurrentWeatherInfo getCurrent() {
		return currentWeatherInfo;
	}

	// 解析到xml文档开头的时候,调用这个方法,可以在其中做一些预处理的工作
	@Override
	public void startDocument() throws SAXException {
		// 实例list集合
		list = new ArrayList<WeatherInfo>();
		super.startDocument();
	}

	// 解析到xml文档结束的时候,调用这个方法,可以在其中做一些善后的工作
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
	}

	/**
	 * 当读到一个开始标签的时候,会触发这个方法
	 * 
	 * localName参数代表不带命名空间前缀的标签的名称 qName参数代表带命名空间前缀的标签的名称
	 * attributes参数表示元素内部属性名和属性值的集合
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub

		// current_conditions这个元素标签
		// 表示当前的天气情况
		// 当解析到这个标签的时候,实例CurrentWeatherInfo
		// 以便保存当前的天气情况
		if ("current_conditions".equals(localName)) {
			currentWeatherInfo = new CurrentWeatherInfo();
		}
		if (!TAG) {
			// 解析到天气情况的时候
			if ("condition".equals(localName)) {
				// 把最天气情况放入到实体中
				currentWeatherInfo.setContent(attributes.getValue("data"));
			}
			// 解析到空气湿度的时候
			if ("humidity".equals(localName)) {
				// 把空气湿度信息放入到实体中
				currentWeatherInfo.setHumidity(attributes.getValue("data"));
			}
			// 解析到风向的时候
			if ("wind_condition".equals(localName)) {
				// 把风向信息放入到实体中
				currentWeatherInfo.setWind_condition(attributes
						.getValue("data"));
			}
		}

		// forecast_conditions这个元素标签
		// 表示一天的天气情况
		// 当解析到这个标签的时候,实例WeatherInfo
		// 以便保存这一天的天气情况
		if ("forecast_conditions".equals(localName)) {
			// 实例WeatherInfo,存放解析到的天气信息
			weatherInfo = new WeatherInfo();
			// 把TAG设置为true
			TAG = true;
		}
		if (TAG) {
			// 解析到日期的时候
			if ("day_of_week".equals(localName)) {
				// 把日期存放在实体中
				weatherInfo.setDate(attributes.getValue("data"));
			}
			// 解析到最低温度的时候
			if ("low".equals(localName)) {
				// 把最低温度放入到实体中
				weatherInfo.setLow(attributes.getValue("data"));
			}
			// 解析到最高温度的时候
			if ("high".equals(localName)) {
				// 把最高温度放入到实体中
				weatherInfo.setHigh(attributes.getValue("data"));
			}
			// 解析到天气情况的时候
			if ("condition".equals(localName)) {
				// 把最天气情况放入到实体中
				weatherInfo.setContent(attributes.getValue("data"));
			}
		}

		super.startElement(uri, localName, qName, attributes);
	}

	/**
	 * 用于处理xml文件中读到的内容
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
	}

	// 解析到结束标签的时候,调用这个方法
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		// 当结束标签为forecast_conditions的时候
		// 把WeatherInfo加入到list列表中,同时设置WeatherInfo为空
		if ("forecast_conditions".equals(qName) && weatherInfo != null) {
			list.add(weatherInfo);
			weatherInfo = null;
		}
		super.endElement(uri, localName, qName);
	}

}


PullWeatherService.java   PULL技术解析xml

package com.feioh;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParserFactory;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Xml;

/**
 * 使用Pull解析XML文件
 * 使用Xml.newPullParser()函数得到解析器
 * 等价于工厂生成的解析器,如:
 * XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
 * XmlPullParser parser=factory.newPullParser();
 * @author yalin
 *
 */
public class PullWeatherService {
	
	public static Map<String,Object> readXML(InputStream inputStream) throws Exception
	{
		List<WeatherInfo> list=null;//存放解析每天天气情况集合
		WeatherInfo weatherInfo=null;//存放解析每天天气
		CurrentWeatherInfo currentWeatherInfo=null;//存放当前天气情况
		boolean TAG = false;// 标识属于哪个标签的天气情况
		
		//得到Pull解析器
//		XmlPullParser parser=Xml.newPullParser();
		XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
		XmlPullParser parser=factory.newPullParser();
		//开始解析...ing
		parser.setInput(inputStream,"UTF-8");
		//获取事件的代码值
		int eventCode=parser.getEventType();
		//如果xml文档没有结束
		while(eventCode != XmlPullParser.END_DOCUMENT)
		{
			switch(eventCode)
			{
			//当开始解析的时候,实例List集合
			case XmlPullParser.START_DOCUMENT:
				list=new ArrayList<WeatherInfo>();
				break;
			case XmlPullParser.START_TAG:
				// current_conditions这个元素标签
				// 表示当前的天气情况
				// 当解析到这个标签的时候,实例CurrentWeatherInfo
				// 以便保存当前的天气情况
				if("current_conditions".equals(parser.getName()))
				{
					currentWeatherInfo=new CurrentWeatherInfo();
				}
				if(!TAG)
				{
					// 解析到天气情况的时候
					if("condition".equals(parser.getName()))
					{
						// 把最天气情况放入到实体中
						currentWeatherInfo.setContent(parser.getAttributeValue(0));
					}
					// 解析到空气湿度的时候
					if("humidity".equals(parser.getName()))
					{
						// 把空气湿度信息放入到实体中
						currentWeatherInfo.setHumidity(parser.getAttributeValue(0));
					}
					// 解析到风向的时候
					if("wind_condition".equals(parser.getName()))
					{
						// 把风向信息放入到实体中
						currentWeatherInfo.setWind_condition(parser.getAttributeValue(0));
					}
				}
				
				// forecast_conditions这个元素标签
				// 表示一天的天气情况
				// 当解析到这个标签的时候,实例WeatherInfo
				// 以便保存这一天的天气情况
				if("forecast_conditions".equals(parser.getName()))
				{
					// 实例WeatherInfo,存放解析到的天气信息
					weatherInfo=new WeatherInfo();
					// 把TAG设置为true
					TAG=true;
				}
				if(TAG)
				{
					// 解析到日期的时候
					if("day_of_week".equals(parser.getName()))
					{
						// 把日期存放在实体中
						weatherInfo.setDate(parser.getAttributeValue(0));
					}
					// 解析到最低温度的时候
					if("low".equals(parser.getName()))
					{
						// 把最低温度放入到实体中
						weatherInfo.setLow(parser.getAttributeValue(0));
					}
					// 解析到最高温度的时候
					if("high".equals(parser.getName()))
					{
						// 把最高温度放入到实体中
						weatherInfo.setHigh(parser.getAttributeValue(0));
					}
					// 解析到天气情况的时候
					if("condition".equals(parser.getName()))
					{
						// 把最天气情况放入到实体中
						weatherInfo.setContent(parser.getAttributeValue(0));
					}
				}
				break;
			case XmlPullParser.END_TAG:
				// 当结束标签为forecast_conditions的时候
				// 把WeatherInfo加入到list列表中,同时设置WeatherInfo为空
				if("forecast_conditions".equals(parser.getName()) && weatherInfo !=null)
				{
					list.add(weatherInfo);
					weatherInfo=null;
				}
				break;
			}
			//进入下一个元素
			eventCode=parser.next();
		}
		
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("everyday",list);
		map.put("current", currentWeatherInfo);
		
		return map;
		
	}
}


MainActivity.java  一个简陋的界面便于显示预报信息

package com.feioh;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	/** Called when the activity is first created. */
	private InputStream inputStream = null;// 定义解析xml的输入流
	private List<WeatherInfo> list = null;// 定义返回每天天气情况列表
	private CurrentWeatherInfo current = null;// 定义当前天气情况
	private TextView tv_everyday, tv_current = null;// 用来显示当前天气情况和每天天气情况
	
	private TextView tv_everyday_pull,tv_current_pull=null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 存放天气情况的TextView
		tv_everyday = (TextView) findViewById(R.id.tv_everyday);
		tv_current = (TextView) findViewById(R.id.tv_current);
		
		tv_everyday_pull = (TextView) findViewById(R.id.tv_everyday_pull);
		tv_current_pull = (TextView) findViewById(R.id.tv_current_pull);
		
		// 解析xml的事件源 按钮
		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(listener);
		
		Button btn_pull=(Button) findViewById(R.id.btn_pull);
		btn_pull.setOnClickListener(listener);
	}
	
	//解析XML事件
	OnClickListener listener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			try {
				// 把要解析的xml放入输入流中
				inputStream = MainActivity.class.getClassLoader().getResourceAsStream("weather.xml");
				// 开始解析xml,返回Map类型数据集
				if(v.getId()==R.id.btn)
				{
					Map<String, Object> map = WeatherService.readXML(inputStream);
					// 得到每天天气情况
					list = (List<WeatherInfo>) map.get("everyday");
					// 得到当前天气情况
					current = (CurrentWeatherInfo) map.get("current");
					
					// 设置显示当前天气情况
					tv_current.setText("");
					tv_current.setText(tv_current.getText() + current.toString());
					// 设置显示每天天气情况
					tv_everyday.setText("");
					if (list != null) {
						for (WeatherInfo weather : list) {
							tv_everyday.setText(tv_everyday.getText()
									+ weather.toString() + "\n");
						}
					}
					
					
				}else if(v.getId()==R.id.btn_pull)
				{
					Map<String, Object> map = PullWeatherService.readXML(inputStream);
					// 得到每天天气情况
					list = (List<WeatherInfo>) map.get("everyday");
					// 得到当前天气情况
					current = (CurrentWeatherInfo) map.get("current");
					
					// 设置显示当前天气情况
					tv_current_pull.setText("");
					tv_current_pull.setText(tv_current_pull.getText() + current.toString());
					// 设置显示每天天气情况
					tv_everyday_pull.setText("");
					if (list != null) {
						for (WeatherInfo weather : list) {
							tv_everyday_pull.setText(tv_everyday_pull.getText()
									+ weather.toString() + "\n");
						}
					}
					
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	};
}


main.xml  最后贴上布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<Button android:layout_width="match_parent"
		android:layout_height="wrap_content" android:id="@+id/btn"
		android:text="SAX解析XML天气预报">
	</Button>
	<TextView android:text="" android:id="@+id/tv_current"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
	</TextView>
	<TextView android:text="" android:id="@+id/tv_everyday"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
	</TextView>
	<Button android:layout_width="match_parent"
		android:layout_height="wrap_content" android:id="@+id/btn_pull"
		android:text="PULL解析XML天气预报">
	</Button>
	<TextView android:text="" android:id="@+id/tv_current_pull"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
	</TextView>
	<TextView android:text="" android:id="@+id/tv_everyday_pull"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
	</TextView>
	
</LinearLayout>

 

查看效果预览:


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值