现在很多文件都是以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); } } }