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, int start, int length) 方法中读取的字符串 String currentValue = new String(ch, start, length) 值为 空,则若不在第三步endElement 内将currentTag = null 的话,则会在第四步 将一个空值再次赋给 student.name .造成了,“刘德华” 这个name被改写为空值 (其实第三步中已经正确赋值为 student.setName("刘德华"); )  。解决办法:在第三步 endElement内最后 currentTag = null .

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

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

     因为characters(char[] ch, int start, int length) 参数里没有当前解析到的节点 qName , 所以你必须知道当前String currentValue = new String(ch, start, 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");

         String age  = 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, String localName, String qName,
			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 localName, 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("********************************************");
		}
		
	}

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值