微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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
}
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 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,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,length);
isintroduction=false;
}
if (isnationality) {
nationality=new String(ch,length);
isnationality=false;
}
if (ispeople) {
}
super.characters(ch,length);
}

}

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

在使用的时候免除了DOM逻辑判断的麻烦,在 endElement中根据标志位和标志位的从属关系判断各个flag,获取数据,就能实现需要的功能。不过DOM可以通过根节点取得各种形式组织的数据,而sax只能通过回调来遍历数据,即不具有随机存储。

原文地址:https://www.jb51.cc/xml/300402.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。