详解使用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;
}
}
}
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;
}
}
}
相关文章推荐
- 详解使用sax解析xml文件的DefaultHandler处理类(转载)
- 详解使用sax解析xml文件的DefaultHandler处理类
- 详解使用sax解析xml文件的DefaultHandler处理类(转载)
- 详解使用sax解析xml文件的DefaultHandler处理类(转载)
- 详解使用sax解析xml文件的DefaultHandler处理类
- 转:VC解析XML文件-CMarkup的使用详解
- Android开发之下载Tomcat服务器的xml文件并使用SAX解析
- PHP使用XMLWriter读写xml文件操作详解
- 【慕课笔记】3-3 应用SAX方式解析XML—使用SAX解析XML文件的节点名和节点间文本
- Android开发--APK反编译就这么简单 详解(附图)和使用AXMLPrinter2.jar批量反编译xml文件
- java中使用j2SE自带的SAX解析XML文件
- android中使用SAX解析xml文件
- 使用SAX解析XML文件(SAX解析)
- Android APK反编译就这么简单 详解(附图)和使用AXMLPrinter2.jar批量反编译xml文件
- 使用SAX解析XML文件
- 关于使用SAX解析xml文件的范例
- 安卓中使用SAX解析XML文件样例
- 使用sax解析xml文件
- Android中使用sax解析xml文件的方法
- 【JavaWeb】XML文件_使用SAX解析将xml文件中的联系人封装为对象