Android中解析XML文件的方法

来源:互联网 发布:网络运维管理系统 编辑:程序博客网 时间:2024/06/06 07:27

1 SAX--Simple API for XML

1.1 SAX简介

SAX是一个解析速度快,并且占用内存少的XML解析器。SAX解析XML文件采用的是事件驱动,也就是它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到字符是否XML语法中的某部分,如果符合则发出事件。所谓的事件其实就是一些回调函数,这些方法定义在ContentHandler接口中,常用的方法有:


1.2 使用SAX读取XML文件

使用SAX读取XML文件时,需要创建一个类实现ContentHandler接口。

此外,我们可以编写一个类继承DefaultHandler类,然后重写里面的方法:

SAXParserFactory saxparserFactory = SAXParserFactory.newInstance();SAXParser saxparser = saxparserFactory.newSAXParser();XMLContentHandler handler = new XMLContentHandler();saxparser.parse(inStream, handler);inStream.close();

示例:

Person.xml

<?xml version="1.0" encoding="UTF-8"?><persons xmlns:pre="http://www.baidu.com"><pre:person id="001"><name>jiaozl</name><age>23</age></pre:person><pre:person id="002"><name>hello</name><age>24</age></pre:person></persons>

Person.java

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;}}
XMLContentHandler.java

public class XMLContentHandler extends DefaultHandler {private static final String TAG = "XMLContentHandler";private List<Person> persons;private Person person;private String preTag;public List<Person> getPersons() {return persons;}@Overridepublic void startDocument() throws SAXException {persons = new ArrayList<Person>();Log.i(TAG, "开始解析...");super.startDocument();}/** * uri:命名空间 * localName:不带命名空间前缀的标签名 * qName:带命名空间前缀的标签名 * attributes:属性集合 */@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("id")));}preTag = localName;Log.i(TAG, "StartEle: uri:" + uri + "; localName:" + localName + "; qName: "+ qName + "attributes: " + attributes);super.startElement(uri, localName, qName, attributes);}/** * ch: 内容 * start:起始位置 * length:长度 */@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if(person!=null) {String data = new String(ch, start, length);if("name".equals(preTag)) {person.setName(data);} else if("age".equals(preTag)) {person.setAge(Integer.valueOf(data));}}Log.i(TAG, "解析内容:"+new String(ch, start, length));}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("person".equals(localName)&&person!=null) {persons.add(person);person = null;}preTag = null;Log.i(TAG, localName + "解析完毕");}@Overridepublic void endDocument() throws SAXException {Log.i(TAG, "文档解析完毕");super.endDocument();}}

SAXPersonService.java
public class SAXPersonService {public static List<Person> readXml(InputStream inStream) throws Exception {SAXParserFactory saxparserFactory = SAXParserFactory.newInstance();SAXParser saxparser = saxparserFactory.newSAXParser();XMLContentHandler handler = new XMLContentHandler();saxparser.parse(inStream, handler);inStream.close();return handler.getPersons();}}


单元测试类:SAXPersonServiceTest.java

public class SAXPersonServiceTest extends AndroidTestCase {private static final String TAG = "SAXPersonServiceTest";public void testReadXml() throws Exception {InputStream inStream = SAXPersonServiceTest.class.getClassLoader().getResourceAsStream("person.xml");List<Person> persons = SAXPersonService.readXml(inStream);for(Person person: persons) {Log.i(TAG, person.toString());}}}

2 DOM--Document Object Model

2.1 DOM简介

Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件。

对于特别大的文档,解析和加载整个文档可能很慢,且很耗资源。

2.2 Dom示例

DOMPersonService.java:

public class DOMPersonService {public static List<Person> readXml(InputStream inStream) throws Exception {List<Person> persons = new ArrayList<Person>();// 实例化一个文档构建器工厂DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 通过文档构建器工厂获取一个文档构建器DocumentBuilder builder = factory.newDocumentBuilder();// 通过文档构建器构建一个文档实例Document document = builder.parse(inStream);Element root = document.getDocumentElement();  // 得到文档根节点NodeList nodes = root.getElementsByTagName("pre:person");for(int i=0; i<nodes.getLength(); i++) {Element personElement = (Element) nodes.item(i);Person person = new Person();person.setId(Integer.valueOf(personElement.getAttribute("id")));NodeList childNodes = personElement.getChildNodes();for(int j=0; j<childNodes.getLength(); j++) {Node childNode = childNodes.item(j);if(childNode.getNodeType() == Node.ELEMENT_NODE) {Element childElement = (Element) childNode;if("name".equals(childElement.getNodeName())) {person.setName(childElement.getFirstChild().getNodeValue());} else {person.setAge(Integer.parseInt(childElement.getFirstChild().getNodeValue()));}}}persons.add(person);}return persons;}}

3 pull

3.1 pull解析简介

Pull解析和Sax解析很相似,都是轻量级的解析,在Android的内核中已经嵌入了Pull,所以我们不需要再添加第三方jar包来支持Pull。
Pull解析和Sax解析不一样的地方有:
①pull读取xml文件后触发相应的事件,调用方法返回的是数字;
②pull可以在程序中控制想解析到哪里就可以停止解析。

3.2 pull解析示例

PullPersonService.java:
public class PullPersonService {public static List<Person> readXml(InputStream inStream) throws Exception {List<Person> persons = null;XmlPullParser parser = Xml.newPullParser();parser.setInput(inStream, "UTF-8");int eventCode = parser.getEventType();Person person = null;while(eventCode!=XmlPullParser.END_DOCUMENT) {switch (eventCode) {case XmlPullParser.START_DOCUMENT: // 文档开始事件persons = new ArrayList<Person>();break;case XmlPullParser.START_TAG: // 开始元素if("person".equals(parser.getName())) {person = new Person();person.setId(Integer.parseInt(parser.getAttributeValue(0)));} else if(null != person) {if("name".equals(parser.getName())) {person.setName(parser.nextText());} else if("age".equals(parser.getName())) {person.setAge(Integer.parseInt(parser.nextText()));}}break;case XmlPullParser.END_TAG:if("person".equals(parser.getName()) && person!=null) {persons.add(person);person=null;}break;default:break;}eventCode = parser.next();}return persons;}}



原创粉丝点击