Java 通过sax解析xml (android相同)

sax是通过事件来解析xml的,它并不会像DOM一样直接一开始就把整个文档读入,而是解到哪,读到哪。这样,当目标xml文件很大的时候,也不会占用很多内存。
简单介绍一下几个主要事件,解析的时候一般就按下面的顺序执行
StartDocument:开始解析文档
StartElement:开始读取元素
characters:读取字符(就是元素内的内容)
EndElement:读取元素结束
endDocument:文档解析结束
其实sax的原理很简单,当读到指定的位置时,触发相应的方法,我们就可以通过重写该方法来记录xml内的数据。
下面开始上实例,还是解析我博客的RSS,地址 http://www.pocketdigi.com/feed, 目标是读取文章标题
首先我们要先自定义一个类,继承DefaultHandler(sax的事件处理类),重写以上事件触发的方法:


package com.pocketdigi;

import java.util.ArrayList;

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

public class XmlHandler extends DefaultHandler {
	String tempName;
	//临时变量用于存储当前读取的标签
	ArrayList temparr=new ArrayList();
	//临时字符串数组用于存储读到的字符串
	ArrayList titles=new ArrayList();
	//存储读到的文章标题
	boolean flag=false;
	//因为博客名称跟标题的标签都是title,所以定时一个flag来区别是博客名称还是文章标题
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		if(tempName.equals("title")&&flag){
			temparr.add(new String(ch,start,length));
		}
		//当前标签是title,并且在item内时,把读到的字符转换成字符串存进临时数组
		//之所以这样做,是回为当要读的标签内容过长时,characters方法不能一次把所有的字符都读进来,而是分多次读
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		if(qName.equals("title")&&flag){
			//title标签读取结束时,把temparr转换成string,存进titles
			String title="";
			for(int i=0;i

然后在程序中调用:


package com.pocketdigi;

import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

public class Main {
	static ArrayList list;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        String content=GetHtml("http://www.pocketdigi.com/feed");
        //获取源码
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			XMLReader reader = factory.newSAXParser().getXMLReader();
			XmlHandler xmlhandler = new XmlHandler();
			reader.setContentHandler(xmlhandler);
			reader.parse(new InputSource(new StringReader(content)));
			ArrayList titles=xmlhandler.titles;
			for (String s:titles){
				//循环输出标题
				System.out.println(s);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
        
  
	}
            //下载源码的方法
	public static String GetHtml(String url){
		try {
			String html="";
			HttpGet httpget=new HttpGet(url);
			DefaultHttpClient httpclient=new DefaultHttpClient();
			HttpResponse response=httpclient.execute(httpget);
			if(response.getStatusLine().getStatusCode()==200){//如果状态码为200,就是正常返回
				html=EntityUtils.toString(response.getEntity());
			}

			return html;  
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "error open url:" + url;  
		} 
	}

}

© 2011, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记