在Android中提供了三種解析XML的方式:SAX(Simple API XML),DOM(Document Objrect Model),以及Android推薦的Pull解析方式.下面就對三種解析方式一一詳細闡述。html
假設要要解析person.xml文檔dom
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1">
<name>zhangsan</name>
<age>21</age>
</person>
<person id="2">
<name>lisi</name>
<age>22</age>
</person>
<person id="3">
<name>wangwu</name>
<age>222</age>
</person>
</persons>函數
首先介紹SAX解析,SAX是事件驅動型XML解析的一個標準接口不會改變 SAX的工做原理簡單地說就是對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數作相應動做,而後繼續一樣的掃描,直至文檔結束。下面結合代碼分析ui
public class SAXPersonService {編碼
public List<Person> getPersons (InputStream instream) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();//建立SAX解析工廠
SAXParser paser = factory.newSAXParser();//建立SAX解析器
PersonPaser personPaser=new PersonPaser();//建立事件處理程序
paser.parse(instream,personPaser);//開始解析
instream.close();//關閉輸入流
return personPaser.getPersons();//返回解析後的內容
}
public final class PersonPaser extends DefaultHandler{//建立事件處理程序,也就是編寫ContentHandler的實現類,通常繼承自DefaultHandler類spa
public List<Person> getPersons() {
return persons;
}
private List<Person> persons=null;
private String tagName=null;
private Person person=null;xml
{htm
//遇到文檔開始標記的時候建立person集合
public void startDocument() throws SAXException persons=new ArrayList<Person>();
}
//遇到元素節點開始時候的處理方法
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tagName = localName;對象
//若是遇到<person>標記,則建立一個person
if("person".equals(tagName)){
person = new Person();
person.setId(new Integer(attributes.getValue(0)));//取出標記內的屬性
} blog
}
//遇到文本節點時的操做
public void characters(char[] ch, int start, int length)
throws SAXException {
if(tagName!=null){//文本節點必須前面要有元素節點開始標記
String data = new String(ch,start,length);//取出文本節點的值
if("name".equals(tagName)){//若是前面的元素節點開始標記是name
person.setName(data);//則將文本節點的值賦值給person的Name
}else if("age".equals(tagName)){//若是前面元素節點開始標記是age
person.setAge(new Short(data));//則將本節點的值賦值給person的Age
}
}
}
//遇到元素節點結束時候的操做
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("person".equals(localName)){//若是遇到</person>標記
persons.add(person);//則將建立完成的person加入到集合中去
person=null;//置空下一個person
}
tagName=null;//置空已有標記,由於要解析下一個節點了
}
}
至此,SAX解析完畢!
下面介紹DOM解析,DOM,即對象文檔模型,它是將整個XML文檔載入內存(因此效率較低,不推薦使用),每個節點當作一個對象,結合代碼分析
public class DomPersonService {
public List<Person> getPersons (InputStream instream) throws Exception{
List<Person> persons = new ArrayList<Person>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//建立DOM解析工廠
DocumentBuilder dombuild = factory.newDocumentBuilder();//建立DON解析器
Document dom = dombuild.parse(instream);//開始解析XML文檔而且獲得整個文檔的對象模型
Element root= dom.getDocumentElement();//獲得根節點<persons>
NodeList personList = root.getElementsByTagName_r("person");//獲得根節點下全部標籤爲<person>的子節點
for(int i = 0;i<personList.getLength();i++){//遍歷person節點
Person person = new Person();//首先建立一個Person
Element personElement = (Element) personList.item(i);//獲得本次Person元素節點
person.setId(new Integer(personElement.getAttribute("id")));//獲得Person節點中的ID
NodeList personChilds = personElement.getChildNodes();//獲得Person節點下的全部子節點
for(int j=0;j<personChilds.getLength();j++){//遍歷person節點下的全部子節點
if(personChilds.item(j).getNodeType()==Node.ELEMENT_NODE){//若是是元素節點的話
Element childElement = (Element) personChilds.item(j); //獲得該元素節點
if("name".equals(childElement.getNodeName())){//若是該元素節點是name節點
person.setName(childElement.getFirstChild().getNodeValue());//獲得name節點下的第一個文本子節點的值
}else if("age".equals(childElement.getNodeName())){//若是該元素節點是age節點、
person.setAge(new Short(childElement.getFirstChild().getNodeValue()));//獲得age節點下的第一個文本字節點的值
}
}
}
persons.add(person);//遍歷完person下的全部子節點後將person元素加入到集合中去
}
return persons;
}
至此,DOM解析方式結束!
下面介紹Pull解析
public class PulPersonService {
public List<Person> getPersons(InputStream instream) throws Exception {
List<Person> persons = null;
Person person = null;
XmlPullParser parser = Xml.newPullParser();//獲得Pull解析器
parser.setInput(instream, "UTF-8");//設置下輸入流的編碼
int eventType = parser.getEventType();//獲得第一個事件類型
while (eventType != XmlPullParser.END_DOCUMENT) {//若是事件類型不是文檔結束的話則不斷處理事件
switch (eventType) {
case (XmlPullParser.START_DOCUMENT)://若是是文檔開始事件
persons = new ArrayList<Person>();建立一個person集合
break;
case (XmlPullParser.START_TAG)://若是遇到標籤開始
String tagName = parser.getName();// 得到解析器當前元素的名稱
if ("person".equals(tagName)) {//若是當前標籤名稱是<person>
person = new Person();//建立一個person
person.setId(new Integer(parser.getAttributeValue(0)));//將元素的屬性值賦值給id
}
if (person != null) {//若是person已經建立完成
if ("name".equals(tagName))//若是當前節點標記是name
person.setName(new String(parser.nextText()));
else if ("age".equals(tagName))//若是當前元素節點標記是age
person.setAge(new Short(parser.nextText()));
}
break;
case (XmlPullParser.END_TAG)://若是遇到標籤結束
if ("person".equals(parser.getName())) {//若是是person標籤結束
persons.add(person);//將建立完成的person加入集合
person = null;//而且置空
}
break;
}
eventType=parser.next();//進入下一個事件處理
}
return persons;
}
至此,三種解析方式已經闡述完畢!
轉載於:http://blog.sina.com.cn/s/blog_5a48dd2d0100sdo9.html