微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sax解析xml实例二



本文用Sax解析另一种风格 xml文件,只要注意两点 1. MyHandler 里不用重写 characters方法 、2.MyHandler中 用的preTag而不是前篇里的currentTag .

1. MyHandler 里不用重写 characters方法

因为weather.xml中是 elementNode(eg: <city data="ShenZhen,GuangDong" />),不是 textNode(eg: <name>刘德华</name>) ,所以不需要用characters方法来读取数据,因此不用重写此方法

注意:若需要characters读取数据,例如前篇 sax解析xml文件实例一(注意endElement 内部最后 currentTag=null),要设置currentTag,并且在endElement内最后 currentTag = null . 因为 <name>刘德华</name>共经历4步:1.startElement 2.characters 3. endElement 4.characters .其中第二步中 characters(char[] ch,int start,int length) 方法中读取的字符串 String currentValue = new String(ch,start,length) 值为"刘德华" 并且赋给student.name,但第四步时,characters(char[] ch,length) 值为 空,则若不在第三步endElement 内将currentTag = null 的话,则会在第四步 将一个空值再次赋给 student.name .造成了,“刘德华”这个name被改写为空值 (其实第三步中已经正确赋值为 student.setName("刘德华"); ) 。解决办法:在第三步 endElement内最后 currentTag = null .

2.MyHandler中 用的preTag而不是前篇里的currentTag .

前篇内设置currentTag,而本篇设置preTag . 看两个程序就很容易理解。关键一句话:若需要characters读取数据,则需要设置currentTag.

因为characters(char[] ch,int length) 参数里没有当前解析到的节点 qName,所以你必须知道当前String currentValue = new String(ch,length) 值对应哪个节点。所以你必须知道当前访问的是哪个节点,或者说你必须知道你想在哪个节点时,取值。

3. 当一个节点有多个属性时,有两种方法取值:

例如: <people name="andy" id="88" age="50" city="hongkong" food="Franch" />

在public void startElement(String url,String localName,String qName,Attributes attributes)

{ 方法一:直接取字段

if("people".equals (qName)){

String name = attributes.getVaue("name");

Stringage = attributes.getVaue("age");

}

方法二:遍历attributes

for(int i=0; i<attributes.getLength(); i++){

String keyName = attributes.getQName(i);

String keyvalue = attributes.getValue(i);


}


}


-------------------------------------------------------------------------------------------------------------------------------------------------

weather.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 深圳的天气情况 -->
<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="ShenZhen,GuangDong" />
            <postal_code data="shenzhen" />
            <latitude_e6 data="" />
            <longitude_e6 data="" />
            <forecast_date data="2011-01-08" />
            <current_date_time data="2011-01-08 23:00:00 +0000" />
            <unit_system data="SI" />
        </forecast_information>
        <current_conditions>
            <condition data="多云" />
            <temp_f data="53" />
            <temp_c data="12" />
            <humidity data="湿度: 43%" />
            <icon data="/ig/images/weather/mostly_cloudy.gif" />
            <wind_condition data="风向: 东北、风速:1 米/秒" />
        </current_conditions>
        <forecast_conditions>
            <day_of_week data="周六" />
            <low data="7" />
            <high data="14" />
            <icon data="/ig/images/weather/chance_of_rain.gif" />
            <condition data="可能有雨" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="周日" />
            <low data="6" />
            <high data="12" />
            <icon data="/ig/images/weather/chance_of_rain.gif" />
            <condition data="可能有雨" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="周一" />
            <low data="5" />
            <high data="10" />
            <icon data="/ig/images/weather/mostly_sunny.gif" />
            <condition data="晴间多云" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="周二" />
            <low data="4" />
            <high data="8" />
            <icon data="/ig/images/weather/chance_of_rain.gif" />
            <condition data="可能有雨" />
        </forecast_conditions>
    </weather>
</xml_api_reply>


客户端java工程目录(左边), 服务器端web工程目录(右边)

客户端 Weather.java

package com.sax.data;

import java.util.List;


/*
 *当前天气信息的类 
 * 
 * 
 * */
public class Weather {

	  /** 城市 * */
    private String city;
    /** 当天日期,格式为yyyy-mm-dd * */
    private String forecase_date;
    /** 当前时间 * */
    private String current_date_time;
    /** 现象描述 * */
    private String current_condition;
    /** 当前干燥程度 * */
    private String current_humidity;
    /** 当前图片地址 * */
    private String current_image_url;
    /** 风向 * */
    private String current_wind;
    /** 此处只能用有序的List集合,因为第一位索引表示当天的天气情况 **/
    private List<Forecast> forecasts;
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getForecase_date() {
		return forecase_date;
	}
	public void setForecase_date(String forecase_date) {
		this.forecase_date = forecase_date;
	}
	public String getCurrent_date_time() {
		return current_date_time;
	}
	public void setCurrent_date_time(String current_date_time) {
		this.current_date_time = current_date_time;
	}
	public String getCurrent_condition() {
		return current_condition;
	}
	public void setCurrent_condition(String current_condition) {
		this.current_condition = current_condition;
	}
	public String getCurrent_humidity() {
		return current_humidity;
	}
	public void setCurrent_humidity(String current_humidity) {
		this.current_humidity = current_humidity;
	}
	public String getCurrent_image_url() {
		return current_image_url;
	}
	public void setCurrent_image_url(String current_image_url) {
		this.current_image_url = current_image_url;
	}
	public String getCurrent_wind() {
		return current_wind;
	}
	public void setCurrent_wind(String current_wind) {
		this.current_wind = current_wind;
	}
	public List<Forecast> getForecasts() {
		return forecasts;
	}
	public void setForecasts(List<Forecast> forecasts) {
		this.forecasts = forecasts;
	}

    
	
	
	
	
	

}


客户端Forecast.java

package com.sax.data;

public class Forecast {

	/*
	 * 未来天气的类
	 * */
	 /** 星期几 * */
    private String day_of_week;
    /** 最低温度 * */
    private String low;
    /** 最高温度 * */
    private String high;
    /** 图片地址 * */
    private String image_url;
    /** 现象描述 * */
    private String condition;
	public String getDay_of_week() {
		return day_of_week;
	}
	public void setDay_of_week(String day_of_week) {
		this.day_of_week = day_of_week;
	}
	public String getLow() {
		return low;
	}
	public void setLow(String low) {
		this.low = low;
	}
	public String getHigh() {
		return high;
	}
	public void setHigh(String high) {
		this.high = high;
	}
	public String getimage_url() {
		return image_url;
	}
	public void setimage_url(String image_url) {
		this.image_url = image_url;
	}
	public String getCondition() {
		return condition;
	}
	public void setCondition(String condition) {
		this.condition = condition;
	}

	
	
}


客户端 Myhandler.java

package com.sax.handler;

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

import javax.xml.namespace.QName;

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

import com.sax.data.Forecast;
import com.sax.data.Weather;

public class MyHandler extends DefaultHandler {

	private Weather weather = null;
	private Forecast forecast = null;
	private List<Forecast> forecasts = null;

	private String preTag = null;
	private String nodeName = null; // 外界传参数的接口参数,本程序体内实际未用到

	public MyHandler(String nodeName) {
		this.nodeName = nodeName;

	}

	public Weather getWeather() {
		return weather;
	}

	@Override
	public void startDocument() throws SAXException {
		// Todo Auto-generated method stub
		super.startDocument();
	}

	@Override
	public void startElement(String url,Attributes attributes) throws SAXException {

		if ("weather".equals(qName)) {
			weather = new Weather();
			forecasts = new ArrayList<Forecast>();
		}
		if ("city".equals(qName)) {

			// 若某个节点有多个属性,可用attributes.getQName(i)和attributes.getValue(i)来遍历获取
			weather.setCity(attributes.getValue("data")); // 城市名
		}
		if ("forecast_date".equals(qName)) {
			weather.setForecase_date(attributes.getValue("data")); // 当前日期
		}
		if ("current_date_time".equals(qName)) {
			weather.setCurrent_date_time(attributes.getValue("data"));// 当前时间
		}
		if ("current_conditions".equals(qName)) {
			/*
			 * 此处的标记非常重要,为下面的 今天的天气 的判断做铺垫,因为condition节点在今天和未来预报里都有。
			 */

			preTag = "current_conditions";
		}
		if ("condition".equals(qName) && preTag.equals("current_conditions")) {
			/*
			 * 如果是preTag="current_conditions"后"condition",则是今天的天气
			 */

			weather.setCurrent_condition(attributes.getValue("data"));

		}
		if ("humidity".equals(qName)) {
			weather.setCurrent_humidity(attributes.getValue("data"));
		}
		if ("icon".equals(qName) && preTag.equals("current_conditions")) {
			weather.setCurrent_image_url(attributes.getValue("data"));
		}
		if ("wind_condition".equals(qName)
				&& preTag.equals("current_conditions")) {
			weather.setCurrent_wind(attributes.getValue("data"));
		}

		if ("forecast_conditions".equals(qName)) {
			forecast = new Forecast();
			preTag = "forecast_conditions"; // 此处 preTag 第二次赋值,重要
		}
		if ("day_of_week".equals(qName) && forecast != null) {
			forecast.setDay_of_week(attributes.getValue("data"));
		}
		if ("low".equals(qName) && forecast != null) {
			forecast.setLow(attributes.getValue("data"));
		}
		if ("high".equals(qName) && forecast != null) {
			forecast.setHigh(attributes.getValue("data"));
		}
		if ("icon".equals(qName) && forecast != null) {
			forecast.setimage_url(attributes.getValue("data"));
		}
		if ("condition".equals(qName) && forecast != null) {
			forecast.setCondition(attributes.getValue("data"));
		}

	}

	@Override
	public void characters(char[] arg0,int arg1,int arg2) throws SAXException {
		// Todo Auto-generated method stub
		super.characters(arg0,arg1,arg2);
	}

	@Override
	public void endElement(String url,String qName)
			throws SAXException {

		if ("forecast_conditions".equals(qName)) {
			forecasts.add(forecast);
			forecast = null;

		}
		if ("weather".equals(qName)) {
			weather.setForecasts(forecasts);
			forecasts = null;
		}
	}

	@Override
	public void endDocument() throws SAXException {
		// Todo Auto-generated method stub
		super.endDocument();
	}

}


客户端 HttpUtils.java

package com.sax.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpUtils {

	public HttpUtils() {
		// Todo Auto-generated constructor stub
	}

	public static InputStream getXML(String path) {

		InputStream inputStream = null;

		try {
			URL url = new URL(path);

			if (url != null) {
				HttpURLConnection httpURLConnection = (HttpURLConnection) url
						.openConnection();
				httpURLConnection.setConnectTimeout(3000);
				httpURLConnection.setDoInput(true); // 从服务器获取数据
				httpURLConnection.setRequestMethod("GET");

				int responseCode = httpURLConnection.getResponseCode();

				if (responseCode == 200) {
					inputStream = httpURLConnection.getInputStream();
				}
			}

		} catch (MalformedURLException e) {
			// Todo Auto-generated catch block
			e.printstacktrace();
		} catch (IOException e) {
			// Todo Auto-generated catch block
			e.printstacktrace();
		}

		return inputStream;

	}

}

客户端SaxService.java

package com.sax.service;

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

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

import com.sax.data.Forecast;
import com.sax.data.Weather;
import com.sax.handler.MyHandler;

public class SaxService {

	private static Weather weather;	
	
    public static Weather readxml(InputStream inputStream,String nodeName){
    	
    	weather = new Weather();
    	try {
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser parser = spf.newSAXParser();
			MyHandler handler = new MyHandler(nodeName);  //本程序中 nodeName实际未用到
			parser.parse(inputStream,handler);
			weather = handler.getWeather();    		
    		
		} catch (Exception e) {
			// Todo: handle exception
		}
    	
    	
    	
    	
    	
    	return weather;
    	
    }
	

}

客户端 Test.java

package com.sax.test;

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

import com.sax.data.Forecast;
import com.sax.data.Weather;
import com.sax.http.HttpUtils;
import com.sax.service.SaxService;

public class Test {



	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// Todo Auto-generated method stub

		InputStream inputStream = HttpUtils.getXML("http://192.168.0.102:8080/myhttp/weather.xml");
		Weather weather = SaxService.readxml(inputStream,"weather");
		
	
		System.out.println("深圳今天天气预报:\n");
		System.out.println("城市 :"+weather.getCity());
		System.out.println("当前天气 :"+weather.getCurrent_condition());
		System.out.println("当前湿度:"+weather.getCurrent_humidity());
		System.out.println("当前风力 :"+weather.getCurrent_wind());
		System.out.println("当前图标 :"+weather.getCurrent_image_url());
		System.out.println("当前日期 :"+weather.getForecase_date());
		System.out.println("当前时间 :"+weather.getCurrent_date_time());
		System.out.println("-------------------------------------------");
		
		System.out.println("\n未来几天的天气预报:\n");
		List<Forecast> list = weather.getForecasts();
		for (Forecast forecast : list) {
			System.out.println("日期:"+forecast.getDay_of_week());
			System.out.println("天气情况:"+forecast.getCondition());
			System.out.println("最低温度:"+forecast.getLow());
			System.out.println("最高温度:"+forecast.getHigh());				
			System.out.println("气象图标:"+forecast.getimage_url());
			System.out.println("********************************************");
		}
		
	}

}




版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类