android解析XML文件的三方法之SAX
16lz
2021-01-23
采用DOM方法读取XML文档,由于使用DOM方法需要将整个XML文档加载内存中,对系统资源占用比较多,这对内存比较紧张的Android系统来说,使用 DOM方法读取XML文档会有很大的限制。 使用SAX方法读取XML,对内存资源的占用的比较少,因此在嵌入式设备中极力推荐使用,Android也不例外,本篇幅详细说明Android中如何使用SAX读取XML文档。
基于事件的处理模式主要围绕着事件源 以及事件处理器 来工作的。一个可以产生事件的对象被称为事件源 ,而可以对事件产生响应的对象就被叫做事件处理器 。事件源与事件处理对象是通过在事件源中的事件注册方法连接的。当事件源产生时间后,调用事件处理器相应的方法,一个事件获得处理。当在事件源调用事件处理器中特定方法的时候,会传递个事件标志以及其响应事件的状态信息,这样事件处理器才能够根据事件信息来决定自己的行为。
在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来开始解析XML文档,并根据文档的内容产生事件。而事件处理器则是org.xml.sax包中的ContentHander、DTDHander、ErrorHandler,以及 EntityResolver这4个接口,它们分别处理事件源在解析XML文档过程中产生的不同种类的事件。而事件源XMLReader与这4个事件处理器的连接是通过在XMLReader中的相应事件处理器注册方法setXXXX()来完成的,详细介绍请见下表:以上的4个事件源处理器接口,在开发中没有必要直接从这4个接口直接继承,因为org.xml.sax.helper包为我们提供了类 DefaultHandler,其继承了这4个个接口,在实际开发中直接从DefaultHandler继承并实现相关函数就可以了。在这4个接口中,最重要的是ContentHanlder接口,下面就其中的方法加以说明,如下:
以上就是解析一个XML文档,事件处理的过程。这里我们对org.xml.sax.XMLReader中的方法做下补充说明:除了前面介绍的一系列事件处理器注册方法set/getXXXX()外,还有个重要的函数:parse(InputSource input)–Parse an XML document,开始解析一个XML文档。 按照应用程序开发的流程,简要介绍下SAX的使用方法首先,编写了解XML文档的结构,按照XML文档的结构,编写具体的数据结构,类似于:XXXXList,XXXXItem,最好与XML的文档保持一致。
其次,开始实现事件处理对象,Android SDK为我们提供了DefaultHandler,其继承了ContentHandler 、DTDHandler、 EntityResolver、 ErrorHandler的所有接口。我们在DefaultHandler的基础上,按照需求实现ContentHanlder的所有接口,这里需要注意 2个方面的问题:
事件处理的顺序,处理时间的位置:一般在startDocument()初始化工作,在endDocument()中收尾的处理工作;startElement()—characters()—endDocument()是一个XML节点读取的过程,startElement()用来初始判断,characters()获取节点的字符数据,endDocument()将数据写入数据结构。
异常SAXException的处理; 然后,XML实体解析,过程如下:
SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();XMLReader xmlreader = parser.getXMLReader();URL rrl = new URL(urlstring);InputSource is = new InputSource(url.openStream());Xmlreader.setContentHanlder(XXXX);Xmlreader.parse(is);最后,在Activity中显示数据,一般先将XML中读取的数据,选择合适的Adaper对数据进行封装,然后使用ListView控件来显示数据。
以上就是SAX读取XML的过程,并显示出最终的数据。以上需要注意的是SAXParserFactory ,SAXParser类来自 javax.xml.parsers包中。 总结说明
SAX读取XML文档的方法,占用内存比较少,但是开发流程相比DOM就复杂多了,具体采用哪种方法比较合适,大家可以在开发的过程中来深刻体会之间的差别。
下面以一个例子给予讲解: 1:person.xml
<?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>李明</name> <age>30</age> </person> <person id="20"> <name>李向梅</name> <age>25</age> </person> </persons>
2:person类
package cn.itcast.domain;public class Person {private Integer id;private String name;private Short age;public Person(){}public Person(Integer id, String name, Short age) {this.id = id;this.name = name;this.age = 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 Short getAge() {return age;}public void setAge(Short age) {this.age = age;}@Overridepublic String toString() {return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";}}
3:SAXPersonService
package cn.itcast.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.itcast.domain.Person;/** * 采用SAX解析XML内容 */public class SAXPersonService {public List<Person> getPersons(InputStream inStream) throws Throwable{SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();PersonParser personParser = new PersonParser();parser.parse(inStream, personParser);inStream.close();return personParser.getPersons();}private final class PersonParser extends DefaultHandler{private List<Person> persons = null;private String tag = null;private Person person = null;public List<Person> getPersons() {return persons;}@Overridepublic void startDocument() throws SAXException {persons = new ArrayList<Person>();}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {if("person".equals(localName)){person = new Person();person.setId(new Integer(attributes.getValue(0)));}tag = localName;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {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 Short(data));}}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("person".equals(localName)){persons.add(person);person = null;}tag = null;}}}
4:测试类PersonTest
public class PersonTest extends AndroidTestCase {private static final String TAG="PersonTest";public void testSAXService()throws Throwable{ SAXService saxservice=new SAXService(); InputStream inStream=this.getClass().getClassLoader().getResourceAsStream("person.xml"); List <Person> persons=saxservice.personService(inStream); for(Person p:persons){ Log.i(TAG,p.toString()); }}}
可参考:http://www.cnblogs.com/zhangdongzi/archive/2011/04/14/2016595.html
更多相关文章
- Android 软键盘监听事件
- Android 中触摸事件的分发和拦截
- 关于Android RenderScript 的详细说明和一些实用文档
- Android中的事件处理机制
- Android的事件处理模式
- 源码角度分析Android的事件输入系统(input system)及ANR原理分析
- Android 4.4 Dialog 被状态栏遮挡的解决方法