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

来源:互联网 发布:三维图纸软件 编辑:程序博客网 时间:2024/05/16 14:59

使用sax解析xml文件是我见到过的最为简单的一种解析xml的方式了。

Java代码
  1. SAXParserFactory factory = SAXParserFactory.newInstance();    
  2. SAXParser parser = factory.newSAXParser();    
  3. XMLReader xmlReader = parser.getXMLReader();    
  4. xmlReader.setContentHandler(mRSSHandler);    
  5. xmlReader.parse(new InputSource(mStream));  

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

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8" ?>       
  2. <rss version="2.0">      
  3. <channel>      
  4. <item>      
  5. <title>Ubuntu11.04(10.04)安装dos工具dosemu</title>       
  6. <link>http://www.ourunix.org/post/276.html</link>       
  7. <author>ourunix@163.com (walfred)</author>       
  8. <category>玩转Linux</category>       
  9. <pubDate>Mon, 16 Jan 2012 22:54:53 +0800</pubDate>       
  10. <comments />       
  11. <description>看完介绍之后,发现这是继wine之后的有一款linux类win工具了,所以现在直接上文介绍dosemu在ubuntu Linux上的安装步骤及使用其运行dos游戏:魂斗罗~~~</description>       
  12. </item>      
  13. </channel>      
  14. </rss>   

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

Java代码
  1. public void startDocument () {  
  2.         //开始解析文档  
  3.     }  
  4.   
  5.     public void endDocument () {  
  6.         //文档解析结束  
  7.     }  
  8.   
  9.     public void startElement (String uri, String localName, String qName, Attributes attributes) {  
  10.         //开始解析节点  
  11.     }  
  12.       
  13.     public void characters (char[] ch, int start, int length) {  
  14.         //保存节点内容  
  15.     }  
  16.       
  17.     public void endElement (String uri, String localName, String qName) {  
  18.         //结束解析节点  
  19.     }  
        一般前两个方法,开始解析和结束解析文档的不需要做处理外,我们的所有操作都是在解析节点部分,我们调用startElement 开始解析节点,然后调用characters 保存节点的内容,最后调用endElement ,如此循环而已,可以看下解析rss的示例:
Java代码
  1. public class RSSHandler extends DefaultHandler {  
  2.     private Context mContext;  
  3.     private RSSItem mRSSItem;  
  4.     private RSSDBInterface mRSSDBInterface;  
  5.       
  6.     private final int TITLE_STATE = 1;  
  7.     private final int AUTHOR_STATE = 2;  
  8.     private final int LINK_STATE = 3;  
  9.     private final int DESCRIPTION_STATE = 4;  
  10.     private final int CATEGORY_STATE = 5;  
  11.     private final int PUBDATE_STATE = 6;  
  12.       
  13.     //标记当前节点  
  14.     private int currentState;  
  15.       
  16.     public RSSHandler(Context ctx){  
  17.         mContext = ctx;  
  18.         //初始化当前节点标记为0  
  19.         currentState = 0;  
  20.         //数据库接口  
  21.         mRSSDBInterface = new RSSDBInterface(mContext);  
  22.     }  
  23.       
  24.     public void startDocument () {  
  25.         //开始解析文档  
  26.         mRSSItem = new RSSItem();
  27.     }  
  28.   
  29.     public void endDocument () {  
  30.         //文档解析结束  
  31.     }  
  32.   
  33.     public void startElement (String uri, String localName, String qName, Attributes attributes) {  
  34.         //开始解析节点  
  35.         if (localName.equals("channel")){  
  36.             return ;  
  37.         }  
  38.           
  39.         if (localName.equals("item")){  
  40.             //当遇到一个item节点时,就实例化一个RSSItem对象  
  41.             mRSSItem = new RSSItem();  
  42.             return;  
  43.         }  
  44.           
  45.         if (localName.equals("title")){  
  46.             currentState = TITLE_STATE;  
  47.             return ;  
  48.         }  
  49.           
  50.         if (localName.equals("author")){  
  51.             currentState = AUTHOR_STATE;  
  52.             return ;  
  53.         }  
  54.           
  55.         if (localName.equals("description")){  
  56.             currentState = DESCRIPTION_STATE;  
  57.             return ;  
  58.         }  
  59.           
  60.         if (localName.equals("link")){  
  61.             currentState = LINK_STATE;  
  62.             return ;  
  63.         }  
  64.           
  65.         if (localName.equals("category")){  
  66.             currentState = CATEGORY_STATE;  
  67.             return ;  
  68.         }  
  69.           
  70.         if (localName.equals("pubDate")){  
  71.             currentState = PUBDATE_STATE;  
  72.             return ;  
  73.         }  
  74.     }  
  75.       
  76.     public void endElement (String uri, String localName, String qName) {  
  77.         //这是节点解析完成时调用的,这里我们遇到item的时候才调用下面的  
  78.         if(localName.equals("item" && mRSSItem != null)){  
  79.             ContentValues values = new ContentValues();  
  80.             values.put(RSSDBInfo.Columns._TITLE, mRSSItem.getTitle());  
  81.             values.put(RSSDBInfo.Columns._AUTHOR, mRSSItem.getAuthor());  
  82.             values.put(RSSDBInfo.Columns._CATEGORY, mRSSItem.getCategory());  
  83.             values.put(RSSDBInfo.Columns._DESCRIPTION, mRSSItem.getDescription());  
  84.             values.put(RSSDBInfo.Columns._LINK, mRSSItem.getLink());  
  85.             values.put(RSSDBInfo.Columns._PUBDATE, mRSSItem.getPubdate());  
  86.             values.put(RSSDBInfo.Columns._ISREAD, RSSUtils.ARTICALE_UNREAD);  
  87.             mRSSDBInterface.insertRSStoDB(values);  
  88.         }  
  89.     }  
  90.       
  91.     public void characters (char[] ch, int start, int length) {  
  92.         String theString = new String(ch, start, length);  
  93.         switch(currentState){  
  94.         case TITLE_STATE:  
  95.             mRSSItem.setTitle(theString);  
  96.             currentState = 0;  
  97.             break;  
  98.               
  99.         case AUTHOR_STATE:  
  100.             mRSSItem.setAuthor(theString);  
  101.             currentState = 0;  
  102.             break;  
  103.               
  104.         case LINK_STATE:  
  105.             mRSSItem.setLink(theString);  
  106.             currentState = 0;  
  107.             break;  
  108.               
  109.         case DESCRIPTION_STATE:  
  110.             mRSSItem.setDescription(theString);  
  111.             currentState = 0;  
  112.             break;  
  113.               
  114.         case CATEGORY_STATE:  
  115.             mRSSItem.setCategory(theString);  
  116.             currentState = 0;  
  117.             break;  
  118.               
  119.         case PUBDATE_STATE:  
  120.             mRSSItem.setPubdate(theString);  
  121.             currentState = 0;  
  122.             break;  
  123.         }  
  124.     }  
  125. }  
原创粉丝点击