Android 用sax解析xml文件

上次提到了用Pull的方法解析xml,這裏又遇到了另外一種用sax DefaultHandler處理類的方法解析xml。

 

SAXParserFactory factory = SAXParserFactory.newInstance();     
SAXParser parser = factory.newSAXParser();     
XMLReader xmlReader = parser.getXMLReader();     
xmlReader.setContentHandler(mRSSHandler);     
xmlReader.parse(new InputSource(mStream));  


sax使用的工廠設計模式,通過,通過ASXParserFactory獲取解析器parser,再從解析器中獲得解析xml文件的xmlReader,但是在xmlReader讀取流式的xml文件時,需要完成一個RSSHandler的設置,它是繼承的DefalutHandler,這裏詳細介紹使用sax解析xml的DefaultHandler處理類。

下面是一個xml的文件格式:

<?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>[email protected] (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處理類就是專門來解析這個文件的,下面是必須完成的藉口:

    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) {   
        //結束解析節點   
    }  

一共5個函數。

一般前兩個方法,開始解析和結束解析文檔不需要做處理外,我們的所有操作都是在解析節點部分,我們調用的startElement開始解析節點,then調用characters保存節點內容,最後調用endElement,如此循環。

示例:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章