因为最近要用到所以从自己的新浪博客中搬过来了原地址: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);
}
}
总结:
Attributes attributes)并把标签名字通过参数给出,
扫描到结束标签的时候调用endElement(String uri, String localName, String qName),并把标签名字通过参数给出。
在使用的时候免除了DOM逻辑判断的麻烦,在
endElement中根据标志位和标志位的从属关系判断各个flag,获取数据,就能实现需要的功能。不过DOM可以通过根节点取得各种形式组织的数据,而sax只能通过回调来遍历数据,即不具有随机存储。