0%

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;  
        } 
    }

}`