一千年的时光,我无数次掀起岁月的帷幔,只为和你,在某一个平静如水的日子相遇,然后相识,倾情一生,缱绻一世,好美的散文,好吧,我情愿把这个“你”当作android;),使用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 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处理类就是专门来解析这个文件的,看下我们必须完成的接口: 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 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; } } } 这就SAX的工厂模式的解析。 注释:ContentValues 是类似Map一样的类,存储键值的。 InputSource 主要就是用的解析的输入流列。 |
|