SAX 解析Xml文件

因为最近要用到所以从自己的新浪博客中搬过来了原地址:http://blog.sina.com.cn/s/blog_a661f16c0101d7cl.html

继续相关博文的部分。

处理思路是:
1:创建SAXParserFactory对象
2: 根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器
3:根据SAXParser解析器获取事件源对象XMLReader
4:实例化一个DefaultHandler对象
5:连接事件源对象XMLReader到事件处理类DefaultHandler中
6:调用XMLReader的parse方法从输入源中获取到的xml数据
7:通过DefaultHandler返回我们需要的数据集合。
一、实例化各种组件
代码:
// 申明SAX方式各组件
SAXParserFactory saxfactory = null;
SAXParser paser = null;
XMLReader reader = null;
XMLHandler handler = null;
// 初始化SAX组件
saxfactory = SAXParserFactory.newInstance();
try {
paser = saxfactory.newSAXParser();
reader = paser.getXMLReader();
handler = new XMLHandler();
reader.setContentHandler(handler);
inputStream =

XmlMainActivity.this.getAssets().open("test.xml");
InputSource input = new InputSource(inputStream);
reader.parse(input);
// XmlMainActivity.this.getResources().getAssets().open("test.xml");
// InputStreamReader isr = new
// InputStreamReader(inputStream, "GB2312");
// InputSource input = new InputSource(isr);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PS:在解析xml文件的时候很容易发生, ExpatParser$ParseException错误。 这次遇到的原因是 name="王XX"age="23" >bbbbbbbb    "王XX"_age 红色处少了一个空格。

二、重写defaultHandler

// 判断标志
private boolean ispeople = false;
private boolean isnationality = false;
private boolean isgraduation = false;
private boolean isintroduction = false;
// 节点、属性的名字
final String mpeoples = "peoples", mpeople = "people", mname = "name",
mage = "age", mnationality = "nationality",
mgraduation = "graduation", mintroduction = "introduction";
声明节点标志和属性KEY值,在endElement时作为判断条件。

代码:
class XMLHandler extends DefaultHandler {

@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
list = null;
super.startDocument();
}

@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
adapter.refresh(list);
// pager.setCurrentItem(2);
super.endDocument();
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
System.out.println("startElement");
Log.i("count a=" + (a++), "uri=" + uri + "   localName="
+ localName + "  qName=" + qName);
//判断节点名称 属性值可以在attributes参数中获取,文本值在character()函数中取得。
if (qName.equals(mpeople)) {
ispeople = true;
name = attributes.getValue(mname);
age = attributes.getValue(mage);
}
if (qName.equals(mnationality)) {
isnationality = true;
}
if (qName.equals(mgraduation)) {
isgraduation = true;
}
if (qName.equals(mintroduction)) {
isintroduction = true;
}

super.startElement(uri, localName, qName, attributes);
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
System.out.println("endElement");
Log.i("count a=" + (a++), "uri=" + uri + "   localName="
+ localName + "  qName=" + qName);
super.endElement(uri, localName, qName);

if (qName.equals(mpeople)) {
if (list == null) {
list = new ArrayList<People>();
}
list.add(new People(name, age, nationality, graduation,
introduction, XmlMainActivity.this));
ispeople=false;
}

}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if (isgraduation){
graduation=new String(ch,start,length);
isgraduation=false;
}
if (isintroduction){
introduction=new String(ch,start,length);
isintroduction=false;
}
if (isnationality) {
nationality=new String(ch,start,length);
isnationality=false;
}
if (ispeople) {
}
super.characters(ch, start, length);
}

}

总结:
  SAX方式解析xml比DOM方便多了,SAX就是简单地遍历一遍xml文件 在遇到开始标签时调用startElement(String uri, String localName, String qName,
Attributes attributes)并把标签名字通过参数给出,
扫描到结束标签的时候调用endElement(String uri, String localName, String qName),并把标签名字通过参数给出。

在使用的时候免除了DOM逻辑判断的麻烦,在 endElement中根据标志位和标志位的从属关系判断各个flag,获取数据,就能实现需要的功能。不过DOM可以通过根节点取得各种形式组织的数据,而sax只能通过回调来遍历数据,即不具有随机存储。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值