您的位置:首页 > 其它

详解使用sax解析xml文件的DefaultHandler处理类

2013-01-17 17:19 330 查看
使用sax解析xml文件是我见到过的最为简单的一种解析xml的方式了。

Java代码

SAXParserFactory factory = SAXParserFactory.newInstance();    
SAXParser parser = factory.newSAXParser();    

XMLReader xmlReader = parser.getXMLReader();    
xmlReader.setContentHandler(mRSSHandler);    

xmlReader.parse(new InputSource(mStream));  

         这里要说明的是sax使用的工厂设计模式,通过SAXParserFactory 获取解析器parser ,在从解析器中获得解析xml文件的xmlReader ,但是在xmlReader 读取流式的xml文件时,需要完成一个RSSHandler的设置,RSSHandler是继承的DefaultHandler,所以这篇文章着重详解使用sax解析xml文件的DefaultHandler处理类。这里我以解析网站的rss.xml文件为例,下面我们先看rss.xml的文件格式:

XML/HTML代码

<?xml version="1.0" encoding="utf-8" ?>       
<rss version="2.0">      

<channel>      
<item>      

<title>Ubuntu11.04(10.04)安装dos工具dosemu</title>       
<link>http://www.ourunix.org/post/276.html</link>       

<author>ourunix@163.com (walfred)</author>       
<category>玩转Linux</category>       

<pubDate>Mon, 16 Jan 2012 22:54:53 +0800</pubDate>       
<comments />       

<description>看完介绍之后,发现这是继wine之后的有一款linux类win工具了,所以现在直接上文介绍dosemu在ubuntu Linux上的安装步骤及使用其运行dos游戏:魂斗罗~~~</description>       
</item>      

</channel>      
</rss>   

        RSSHandler继承的DefaultHandler处理类就是专门来解析这个文件的,看下我们必须完成的接口:

Java代码

public void startDocument () {  
        //开始解析文档  

    }  
  

    public void endDocument () {  
        //文档解析结束  

    }  
  

    public void startElement (String uri, String localName, String qName, Attributes attributes) {  
        //开始解析节点  

    }  
      

    public void characters (char[] ch, int start, int length) {  
        //保存节点内容  

    }  
      

    public void endElement (String uri, String localName, String qName) {  
        //结束解析节点  

    }  

        一般前两个方法,开始解析和结束解析文档的不需要做处理外,我们的所有操作都是在解析节点部分,我们调用startElement 开始解析节点,然后调用characters 保存节点的内容,最后调用endElement ,如此循环而已,可以看下解析rss的示例:

Java代码

public class RSSHandler extends DefaultHandler {  
    private Context mContext;  

    private RSSItem mRSSItem;  
    private RSSDBInterface mRSSDBInterface;  

      
    private final int TITLE_STATE = 1;  

    private final int AUTHOR_STATE = 2;  
    private final int LINK_STATE = 3;  

    private final int DESCRIPTION_STATE = 4;  
    private final int CATEGORY_STATE = 5;  

    private final int PUBDATE_STATE = 6;  
      

    //标记当前节点  
    private int currentState;  

      
    public RSSHandler(Context ctx){  

        mContext = ctx;  
        //初始化当前节点标记为0  

        currentState = 0;  
        //数据库接口  

        mRSSDBInterface = new RSSDBInterface(mContext);  
    }  

      
    public void startDocument () {  

        //开始解析文档  

        mRSSItem = new RSSItem();
    }  

  
    public void endDocument () {  

        //文档解析结束  
    }  

  
    public void startElement (String uri, String localName, String qName, Attributes attributes) {  

        //开始解析节点  
        if (localName.equals("channel")){  

            return ;  
        }  

          
        if (localName.equals("item")){  

            //当遇到一个item节点时,就实例化一个RSSItem对象  
            mRSSItem = new RSSItem();  

            return;  
        }  

          
        if (localName.equals("title")){  

            currentState = TITLE_STATE;  
            return ;  

        }  
          

        if (localName.equals("author")){  
            currentState = AUTHOR_STATE;  

            return ;  
        }  

          
        if (localName.equals("description")){  

            currentState = DESCRIPTION_STATE;  
            return ;  

        }  
          

        if (localName.equals("link")){  
            currentState = LINK_STATE;  

            return ;  
        }  

          
        if (localName.equals("category")){  

            currentState = CATEGORY_STATE;  
            return ;  

        }  
          

        if (localName.equals("pubDate")){  
            currentState = PUBDATE_STATE;  

            return ;  
        }  

    }  
      

    public void endElement (String uri, String localName, String qName) {  
        //这是节点解析完成时调用的,这里我们遇到item的时候才调用下面的  

        if(localName.equals("item" &&
mRSSItem != null)){  
            ContentValues values = new ContentValues();  

            values.put(RSSDBInfo.Columns._TITLE, mRSSItem.getTitle());  
            values.put(RSSDBInfo.Columns._AUTHOR, mRSSItem.getAuthor());  

            values.put(RSSDBInfo.Columns._CATEGORY, mRSSItem.getCategory());  
            values.put(RSSDBInfo.Columns._DESCRIPTION, mRSSItem.getDescription());  

            values.put(RSSDBInfo.Columns._LINK, mRSSItem.getLink());  
            values.put(RSSDBInfo.Columns._PUBDATE, mRSSItem.getPubdate());  

            values.put(RSSDBInfo.Columns._ISREAD, RSSUtils.ARTICALE_UNREAD);  
            mRSSDBInterface.insertRSStoDB(values);  

        }  
    }  

      
    public void characters (char[] ch, int start, int length) {  

        String theString = new String(ch, start, length);  
        switch(currentState){  

        case TITLE_STATE:  
            mRSSItem.setTitle(theString);  

            currentState = 0;  
            break;  

              
        case AUTHOR_STATE:  

            mRSSItem.setAuthor(theString);  
            currentState = 0;  

            break;  
              

        case LINK_STATE:  
            mRSSItem.setLink(theString);  

            currentState = 0;  
            break;  

              
        case DESCRIPTION_STATE:  

            mRSSItem.setDescription(theString);  
            currentState = 0;  

            break;  
              

        case CATEGORY_STATE:  
            mRSSItem.setCategory(theString);  

            currentState = 0;  
            break;  

              
        case PUBDATE_STATE:  

            mRSSItem.setPubdate(theString);  
            currentState = 0;  

            break;  
        }  

    }  
}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: