Android中的三種XML解析方式

在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

相關文章
相關標籤/搜索