一千年的时光,我无数次掀起岁月的帷幔,只为和你,在某一个平静如水的日子相遇,然后相识,倾情一生,缱绻一世,好美的散文,好吧,我情愿把这个“你”当作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
,但是在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处理类就是专门来解析这个文件的,看下我们必须完成的接口:

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的示例:

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 主要就是用的解析的输入流列。

sax解析xml文件的DefaultHandler处理类的更多相关文章

  1. 用SAX解析xml文件,java

    (此文为(https://www.imooc.com/video/4482)之随笔) 1.用SAX解析xml文件大致分为三步 写了一个XML文件作为例子 (1)main方法代码如下: import j ...

  2. JAVA使用SAX解析XML文件

    在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...

  3. SAX解析xml文件

    需要做一个银行名字的列表. 因为有很多,所以想到了用xml来保存,然后uongDAX解析. public class BankSelectActivity extends BaseActivity{ ...

  4. 安卓SAX解析XML文件

    XML文件经常使用的解析方式有DOM解析,SAX解析. 一.Sax SAX(simpleAPIforXML)是一种XML解析的替代方法. 相比于DOM.SAX是一种速度更快,更有效的方法. 它逐行扫描 ...

  5. cocos2d-x 3.0 使用Sax解析xml文件(中国显示器问题解决)

    今天是个好日子.我以为事情可以变得,明天是个好日子.打开门儿春风... 恩,听着歌写文档生活就是这么享受. 今天曾经的邻居大神突然在qq上赞了我一下,这让我异常激动啊.. 这还要从前前前几天说起,那会 ...

  6. Python—使用xml.sax解析xml文件

    什么是sax? SAX是一种基于事件驱动的API. 利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器. 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件; 而事件处 ...

  7. sax解析xml文件,封装到对象中

    创建User.java类 public class User { private String id; private String name; private String age; private ...

  8. Java中实现SAX解析xml文件到MySQL数据库

    大致步骤: 1.Java bean 2.DBHelper.java 3.重写DefaultHandler中的方法:MyHander.java 4.循环写数据库:SAXParserDemo.java ① ...

  9. 使用SAX解析XML文件

    SAX这是Simple API for XML缩写,它不是由引起W3C拟议标准正式.尽管如此,使用SAX很少几个,点儿全部的XML解析器都会支持它. 与DOM比較而言,SAX是一种轻量型的方法. 我们 ...

随机推荐

  1. POJ 1106

    先判断是否在圆内,然后用叉积判断是否在180度内.枚举判断就可以了... 感觉是数据弱了.. #include <iostream> #include <cstdio> #in ...

  2. Intent 使用方法全面总结

    调用拨号程序 // 给移动客服10086拨打电话 Uri uri = Uri.parse("tel:10086"); Intent intent = new Intent(Inte ...

  3. 什么是A记录、MX记录、CNAME记录具体介绍

    什么是A记录: A (Address) 记录是用来指定主机名(或域名)相应的IP地址记录.用户能够将该域名下的站点服务器指向到自己的web server上. 同一时候也能够设置域名的子域名. 通俗来说 ...

  4. C语言播放声音最简单的两种方法

    1. 假设仅须要播放波形文件wav格式的声音,非常easy.仅仅需一句话: PlaySound(TEXT("Data\\1.wav"), NULL, SND_FILENAME | ...

  5. SpringBoot之表单验证@Valid

    转自:https://www.cnblogs.com/chenlove/p/8708627.html SpringBoot提供了强大的表单验证功能实现,给我们省去了写验证的麻烦: 这里我们给下实例,提 ...

  6. [专辑] 也晒晒我的RBAC系统 ——行一山人的博客

    也晒晒我的RBAC系统(一):概述 也晒晒我的RBAC系统(二):系统实现原理简介 也晒晒我的RBAC系统(三):后台管理程序源码及使用演示 也晒晒我的RBAC系统(四):框架源代码(超值奉献,请勿拍 ...

  7. NSKeyedUnarchiver归档

    把自定义的类对象编码到NSData中 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:bc];//归档,bc是一个自定义的类对象, ...

  8. MySQL视图、触发器、事务、存储过程、函数

    视图.触发器.事务.存储过程.函数   阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据 ...

  9. IOS-UITextField-改变光标颜色

    方法1: [[UITextField appearance] setTintColor:[UIColor blackColor]]; 这种方法将影响所有TextField. 方法2: textFiel ...

  10. html行级元素和块级元素以及css转换

    之前有说过html的标签是有语义的,当然也就有一些默认的样式,比如标题有h1···h6,他们的字体由大至小一次递减,字体比一般字体要加粗. 这样也就有了行级元素和块级元素,下面来看看什么是行级元素什么 ...