DOM解析需要预加载文档,在嵌入式开发中,内存比较紧俏,所以不推介,此处不详述!下面具体介绍怎么使用SAX与PULL解析XML文件。
首先创建person.xml文件(xml文件包含元素节点与文本节点)
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="20">
<name>张进</name>
<age>22</age>
</person>
<person id="30">
<name>小明</name>
<age>28</age>
</person>
</persons>
在创建Person对象
public class Person { public int id ; public String name ; public int age ; @Override public String toString() { return "id : "+id+" name : "+name+" age "+age ; } }
使用SAX解析开始:(SAX事件驱动型解析方式)
public class SaxParser { public List <Person> readXml(InputStream is){ try { SAXParser mSAXParser = SAXParserFactory.newInstance().newSAXParser(); PersonHandler mPersonHandler = new PersonHandler(); mSAXParser.parse(is, mPersonHandler); is.close(); return mPersonHandler.getPersons(); } catch (Exception e) { e.printStackTrace(); } return null ; } private final class PersonHandler extends DefaultHandler{ private List<Person> list = null ; private String tag = null ; private Person person ; @Override public void startDocument() throws SAXException { list = new ArrayList<Person>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if("person".equals(localName)){ person = new Person(); person.id = Integer.parseInt(attributes.getValue(0)); } tag = localName ; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if("person".equals(localName)){ list.add(person); person = null ; } tag = null ; } @Override public 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.name = data ; }else if("age".equals(tag)){ person.age = Integer.parseInt(data); } } } public List<Person> getPersons (){ return this.list ; } } }
使用PULL解析方式:
public class PullParse { private List<Person> list ; public List<Person> getPersons(InputStream is){ XmlPullParser mXmlPullParser = Xml.newPullParser(); Person person = null ; try { mXmlPullParser.setInput(is, "UTF-8"); //产生第一个事件
int eventType = mXmlPullParser.getEventType(); while(eventType != XmlPullParser.END_DOCUMENT){ switch (eventType) { case XmlPullParser.START_DOCUMENT: list = new ArrayList<Person>(); break; case XmlPullParser.START_TAG: //得到解析器当前指向元素节点的便签名 String name = mXmlPullParser.getName(); if("person".equals(name)){ person = new Person(); person.id = Integer.parseInt(mXmlPullParser.getAttributeValue(0)); }else if(person != null){ if("name".equals(name)){ //得到解析器当前指向元素节点的下一个文本节点 person.name = mXmlPullParser.nextText(); }else if("age".equals(name)){ person.age = Integer.parseInt(mXmlPullParser.nextText()); } } break ; case XmlPullParser.END_TAG: if("person".equals(mXmlPullParser.getName())){ list.add(person); person = null ; } break ; } eventType = mXmlPullParser.next(); } } catch (Exception e) { e.printStackTrace(); } return list ; } }
使用JUNIT进行单元测试
public class TestXmlParse extends AndroidTestCase { public void testReadXml(){ InputStream is = this.getClass().getClassLoader().getResourceAsStream("person.xml"); SaxParser mSaxParser = new SaxParser(); List<Person> list = mSaxParser.readXml(is); for(Person p : list) System.out.println(p); } public void TestGetPersons(){ InputStream is = this.getClass().getClassLoader().getResourceAsStream("person.xml"); PullParse mPullParse = new PullParse(); List<Person> list = mPullParse.getPersons(is); for(Person p : list) System.out.println(p); } }
说明:SAX解析比较难以理解,PULL解析是android官方采用的,代码复杂度不高,效率略高