现在很多文件都是以XML格式存放的。在Android平台上可以使用Simple API for XML(SAX)、Document Object Model(DOM)(不建议使用)和Android附带的pull解析器解析XML文件三种方式。
本文主要讲使用SAX读取XML文件;它是一种解析速度快并且占内存少的xml解析器,非常适合用于Android等移动设备,SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否符合XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些方法,这些方法定义在ContentHandler接口。
下面根据个小例子理解SAX解析技术:
要解析的文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>zhangsan</name>
<age>30</age>
</person>
<person id="20">
<name>zhangxiaoxiao</name>
<age>25</age>
</person>
</persons>
将上面的文件写入新建的person.xml文件放入src相应的xml包里面。
1..新建Person类
package cn.bzu.entity;
public class Person {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
2.新建SAXPersonService,对xml文件进行解析。
package cn.bzu.service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import cn.bzu.entity.Person;
public class SAXPersonService {
// 要解析的XML文件以流的方式传进来
public List<Person> getPersons(InputStream istream) throws Throwable {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
PersonHanler personHanler = new PersonHanler();
saxParser.parse(istream, personHanler);
// 当解析过程中遇到符合XML语法规定的语句时就会调用第2个参数所规定的方法
return personHanler.getPersons();
}
private final class PersonHanler extends DefaultHandler {
private List<Person> persons;
private Person person;
private String TAG;// 存放当前所遍历的元素节点
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
if (TAG != null){
String data=new String(ch, start, length);
if ("name".equals(TAG)) {
person.setName(data);
} else if ("age".equals(TAG)) {
person.setAge(new Integer(data));
}
}
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if("person".equals(localName)){
persons.add(person);
person=null;
}
TAG=null;
}
// 进行一些初始化的工作
@Override
public void startDocument() throws SAXException {
super.startDocument();
persons = new ArrayList<Person>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
// localName:不含命名空间前缀的标签名
// qName:含有命名空间前缀的标签名
// attributes:接收属性值
if ("person".equals(localName)) {
person = new Person();
person.setId(new Integer(attributes.getValue(0)));
}
TAG = localName;
}
public List<Person> getPersons() {
return persons;
}
}
}
3.新建SAXPersonServiceTest类,进行单元测试。
package cn.bzu.service;
import java.io.InputStream;
import java.util.List;
import cn.bzu.entity.Person;
import android.test.AndroidTestCase;
public class SAXPersonServiceTest extends AndroidTestCase {
public void testSAX() throws Throwable{
SAXPersonService saxPersonService=new SAXPersonService();
InputStream istream=getClass().getClassLoader().getResourceAsStream("cn/bzu/xml/persons.xml");
List<Person> persons=saxPersonService.getPersons(istream);
for(Person person:persons){
System.out.println(person);
}
}
}