Android解析XML之SAX解析器
SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。
SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。
SAX相关类及API
DefaultHandler:是一个事件处理器,可以接收解析器报告的所有事件,处理所发现的数据。它实现了EntityResolver接口、DTDHandler接口、ErrorHandler接口和ContentHandler接口。这几个接口代表不同类型的事件处理器。
利用SAX解析XML,实际上只需要继承DefaultHandler类,然后重写几个关键性方法即可。一般我们需要重写的方法是startDocument、startElement、characters、endElement和endDocument方法。
API解释:
1 import org.xml.sax.Attributes; 2 import org.xml.sax.SAXException; 3 import org.xml.sax.helpers.DefaultHandler; 4 5 public class MyParser extends DefaultHandler{ 6 7 /** 8 * 当文档开始解析时此函数被调用 9 * 10 * 通常我们需要在这里面做一些初始化的工作,比如分配某些资源 11 */ 12 @Override 13 public void startDocument() throws SAXException { 14 super.startDocument(); 15 } 16 17 /** 18 * 当扫描到文档元素节点起始标志时被调用 19 * 20 * 通常我们需要做一下标记,或者分配节点资源。 21 */ 22 @Override 23 public void startElement(String uri, String localName, String qName, 24 Attributes attributes) throws SAXException { 25 super.startElement(uri, localName, qName, attributes); 26 } 27 28 /** 29 * 扫描到元素节点中的字符串内容时调用此函数 30 * @param ch 代表元素内容的字符数组(实测时候并不完全表示元素内容,不过这不影响) 31 * @param start 能够使用的起始位置 32 * @param length 能够使用的数组长度 33 */ 34 @Override 35 public void characters(char[] ch, int start, int length) 36 throws SAXException { 37 super.characters(ch, start, length); 38 } 39 40 41 /** 42 * 扫描到元素节点结束标志时调用 43 * 44 * 应该是最重要的一个方法。需要判断节点名作相应的数据解析。 45 * @param localName 节点名字 46 * @param qName 含限定符的节点名字 47 */ 48 @Override 49 public void endElement(String uri, String localName, String qName) 50 throws SAXException { 51 super.endElement(uri, localName, qName); 52 } 53 54 /** 55 * 扫描文档结束后调用 56 * 57 * 如果有些资源需要释放的话,就在这里做好了。 58 */ 59 @Override 60 public void endDocument() throws SAXException { 61 super.endDocument(); 62 } 63 64 }
实例
需要解析的persons.xml文件内容如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <persons> 3 <person id="1" group="1"> 4 <name>张三</name> 5 <age>24</age> 6 </person> 7 <person id="2" group="2"> 8 <name>李四</name> 9 <age>25</age> 10 </person> 11 <person id="3" group="1"> 12 <name>王五</name> 13 <age>26</age> 14 </person> 15 </persons>
定义Person实体类:
/** * Created by Shane on 2015/4/24. */ public class Person { private int id; private int group; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getGroup() { return group; } public void setGroup(int group) { this.group = group; } 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; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("name: " + name); sb.append(", age: " + age); sb.append(", id: " + id); sb.append(", group: " + group); return sb.toString(); } }
定义用于解析XML文件的解析器PersonSAXHandler 类如下:
/** * Created by Shane on 2015/4/24. */ public class PersonSAXHandler extends DefaultHandler{ private static final String TAG_PERSON = "person"; private static final String TAG_NAME = "name"; private static final String TAG_AGE = "age"; private List<Person> persons; private Person person; private StringBuffer stringBuffer; public List<Person> getPersons() { return persons; } @Override public void startDocument() throws SAXException { super.startDocument(); persons = new ArrayList<>(); stringBuffer = new StringBuffer(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if (localName.equals(TAG_PERSON)) { person = new Person(); person.setId(Integer.parseInt(attributes.getValue(0))); person.setGroup(Integer.parseInt(attributes.getValue(1))); } stringBuffer.setLength(0); // start a new string buffer. } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); stringBuffer.append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if (localName.equals(TAG_PERSON)) { persons.add(person); } else if (localName.equals(TAG_NAME)) { person.setName(stringBuffer.toString().trim()); } else if (localName.equals(TAG_AGE)) { person.setAge(Integer.parseInt(stringBuffer.toString().trim())); } } @Override public void endDocument() throws SAXException { super.endDocument(); } }
包装上述PersonSAXHandler类,定义PersonSAXParser类进行解析:
/** * Created by Shane on 2015/4/24. */ public class PersonSAXParser implements PersonParser{ @Override public List<Person> parse(InputStream inputStream) { List<Person> persons = new ArrayList<>(); try { SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); PersonSAXHandler personSAXHandler = new PersonSAXHandler(); saxParser.parse(inputStream, personSAXHandler); persons = personSAXHandler.getPersons(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) {} } } return persons; } }
PersonParser接口定义如下:
/** * Created by Shane on 2015/4/24. */ public interface PersonParser {
public List<Person> parse(InputStream inputStream);
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。