在Android里用SAX方式解析XML文件

来源:互联网 发布:dhcp服务器需要mac 编辑:程序博客网 时间:2024/06/15 22:25

开发当中经常会用到解析XML文件的技术,SAX是一种非常快速的解析方式,以一种流的方式从头到尾顺序读取。

使用SAX方式要自定义一个解析类实现ContentHandler接口,这个接口中有好多方法,但是并不是每个方法都需要实现,其中有几个方法常用:

ContentHandler接口的方法有以下几种:  void startDocument(); // 文档解析开始时执行  void endDocument(); // 文档解析结束时执行  void startElement(String uri, String localName, String qName, Attributes atts); // 标签开始解析时执行  void endElement(String uri, String localName, String qName, Attributes atts); // 标签解析结束时执行  void characters(char[] ch, int start, int length ); // 解析标签属性时执行 

ContentHandler有一个实现类DefaultHandler,我们通常继承这个类,然后重写以上几个方法。

首先在src下建一个data.xml文件

<?xml version="1.0" encoding="utf-8"?><persons>    <person id="101">        <name>jack</name>        <age>28</age>    </person>    <person id="102">        <name>rose</name>        <age>27</age>    </person></persons>

相应的我们建一个实体类Person来存放解析结果

package com.example.test;public class Person {private int id;private String name;private int age;public Person() {}public Person(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";}}

然后定义我们的解析规则类,继承DefaultHandler,并重写其中几个方法

package com.example.test;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;public class SaxXMLParserHandler extends DefaultHandler {/** 保存解析到的每一个person */private List<Person> persons;/** 保存当前正在解析的person */private Person person;/** 保存当前解析到的标签名称 */private String tag;/** * 解析到文档开头会调用此方法 */@Overridepublic void startDocument() throws SAXException {// 文档一开始就初始化集合persons = new ArrayList<Person>();}/** * 解析到文档结尾会调用此方法 */@Overridepublic void endDocument() throws SAXException {}/** * 解析到文档开头会调用此方法 *  * uri 是命名空间  * localName 标签的名称,如name, age等  * qName 带命名空间的标签名  * attributes 存放改标签的所有属性  */ @Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes)throws SAXException {// 解析到person标签开头就初始化一个personif ("person".equals(localName)) {person = new Person();// 从person标签里面拿到属性id的值int id = Integer.parseInt(attributes.getValue("id"));person.setId(id);}// 将解析到的标签名缓存起来tag = localName;}/** * 解析到会调用此方法 */@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {// 解析到person标签的结尾表示一个person解析完毕if ("person".equals(localName)) {// 解析完的person加到集合里面persons.add(person);// 把当前正在解析的person置为nullperson = null;}// 把当前解析的标签名称置为nulltag = null;}/** * 遇到标签里面的内容时调用此方法 */@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {// 把标签里面的文本内容构造成字符串String str = new String(ch, start, length).trim();// 根据当前标签名称判断标签里的文本是name还是ageif ("name".equals(tag)) {person.setName(str);} else if ("age".equals(tag)) {person.setAge(Integer.parseInt(str));}}public static List<Person> parse() throws Exception {// 通过工厂获取一个sax解析器SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();// 从src目录下的data.xml文件获取输入流InputStream in = SaxXMLParserHandler.class.getClassLoader().getResourceAsStream("data.xml");// 构造一个解析对象,就是当前所在类的对象SaxXMLParserHandler handler = new SaxXMLParserHandler();// 设置输入流和解析类parser.parse(in, handler);// 解析完之后persons集合里面就有值了return handler.persons;}}

就这样解析就完成了,我们来测试一下,来到Activity里面

package com.example.test;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);try {List<Person> persons = SaxXMLParserHandler.parse();for (Person person : persons) {Log.i(TAG, person.toString());}} catch (Exception e) {e.printStackTrace();}}}

在模拟器里运行一下程序,我们能看到已经解析成功:


0 0
原创粉丝点击