三種解析xml的方式-創(chuàng)新互聯(lián)

在Android平臺(tái)上可以使用Simple?API?for XML(SAX) 、 Document Object Model(DOM)和Android附帶的pull解析器解析XML文件。

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),柘城企業(yè)網(wǎng)站建設(shè),柘城品牌網(wǎng)站建設(shè),網(wǎng)站定制,柘城網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,柘城網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

下面是本例子要解析的XML文件:itcast.xml

  <?xml version="1.0" encoding="UTF-8"?>

  <persons>

    <person id="23">

      <name>李明</name>

      <age>30</age>

    </person>

    <person id="20">

      <name>李向梅</name>

      <age>25</age>

    </person>

  </persons>

例子定義了一個(gè)javabean用于存放上面解析出來(lái)的xml內(nèi)容, 這個(gè)javabean為Person,代碼:

  public class Person {

    private Integer id;

    private String name;

  private Short 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 Short getAge() {

      return age;

    }

    public void setAge(Short age) {

      this.age = age;

    }

  }

1. SAX解析XML文件

SAX是一個(gè)解析速度快并且占用內(nèi)存少的xml解析器,非常適合用于Android等移動(dòng)設(shè)備。?SAX解析XML文件采用的是事件驅(qū)動(dòng),也就是說(shuō),它并不需要解析完整個(gè)文檔,在按內(nèi)容順序解析文檔的過程中,SAX會(huì)判斷當(dāng)前讀到的字符是否合法XML語(yǔ)法中的某部分,如果符合就會(huì)觸發(fā)事件。所謂事件,其實(shí)就是一些回調(diào)(callback)方法,這些方法(事件)定義在ContentHandler接口。

  public static List<Person> readXML(InputStream inStream) {

    try {

      //創(chuàng)建解析器

      SAXParserFactory spf = SAXParserFactory.newInstance();

      SAXParser saxParser = spf.newSAXParser();

      //設(shè)置解析器的相關(guān)特性,true表示開啟命名空間特性

      saxParser.setProperty("http://xml.org/sax/features/namespaces",true);

      XMLContentHandler handler = new XMLContentHandler();

      saxParser.parse(inStream, handler);

      inStream.close();

      return handler.getPersons();

    } catch (Exception e) {

      e.printStackTrace();

    }

    return null;

  }

  //SAX類:DefaultHandler,它實(shí)現(xiàn)了ContentHandler接口。在實(shí)現(xiàn)的時(shí)候,只需要繼承該類,重載相應(yīng)的方法即可。

  public class XMLContentHandler extends DefaultHandler {

    private List<Person> persons = null;

    private Person currentPerson;

    private String tagName = null;//當(dāng)前解析的元素標(biāo)簽

    public List<Person> getPersons() {

      return persons;

    }

    //接收文檔開始的通知。當(dāng)遇到文檔的開頭的時(shí)候,調(diào)用這個(gè)方法,可以在其中做一些預(yù)處理的工作。

    @Override

    public void startDocument() throws SAXException {

      persons = new ArrayList<Person>();

    }

    //接收元素開始的通知。當(dāng)讀到一個(gè)開始標(biāo)簽的時(shí)候,會(huì)觸發(fā)這個(gè)方法。其中namespaceURI表示元素的命名空間;

    //localName表示元素的本地名稱(不帶前綴);qName表示元素的限定名(帶前綴);atts 表示元素的屬性集合

    @Override

    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {

      if(localName.equals("person")){

        currentPerson = new Person();

        currentPerson.setId(Integer.parseInt(atts.getValue("id")));

      }

      this.tagName = localName;

    }

    //接收字符數(shù)據(jù)的通知。該方法用來(lái)處理在XML文件中讀到的內(nèi)容,第一個(gè)參數(shù)用于存放文件的內(nèi)容,

    //后面兩個(gè)參數(shù)是讀到的字符串在這個(gè)數(shù)組中的起始位置和長(zhǎng)度,使用new String(ch,start,length)就可以獲取內(nèi)容。

    @Override

    public void characters(char[] ch, int start, int length) throws SAXException {

      if(tagName!=null){

        String data = new String(ch, start, length);

        if(tagName.equals("name")){

          this.currentPerson.setName(data);

        }else if(tagName.equals("age")){

          this.currentPerson.setAge(Short.parseShort(data));

        }

      }

    }

    //接收文檔的結(jié)尾的通知。在遇到結(jié)束標(biāo)簽的時(shí)候,調(diào)用這個(gè)方法。其中,uri表示元素的命名空間;

    //localName表示元素的本地名稱(不帶前綴);name表示元素的限定名(帶前綴)

    @Override

    public void endElement(String uri, String localName, String name) throws SAXException {

      if(localName.equals("person")){

        persons.add(currentPerson);

        currentPerson = null;

      }

      this.tagName = null;

    }

  }

2. DOM解析XML文件

DOM解析XML文件時(shí),會(huì)將XML文件的所有內(nèi)容讀取到內(nèi)存中,然后允許您使用DOM API遍歷XML樹、檢索所需的數(shù)據(jù)。使用DOM操作XML的代碼看起來(lái)比較直觀,并且,在某些方面比基于SAX的實(shí)現(xiàn)更加簡(jiǎn)單。但是,因?yàn)镈OM需要將XML文件的所有內(nèi)容讀取到內(nèi)存中,所以內(nèi)存的消耗比較大,特別對(duì)于運(yùn)行Android的移動(dòng)設(shè)備來(lái)說(shuō),因?yàn)樵O(shè)備的資源比較寶貴,所以建議還是采用SAX來(lái)解析XML文件,當(dāng)然,如果XML文件的內(nèi)容比較小采用DOM是可行的。

public static List<Person> readXML(InputStream inStream) {

  List<Person> persons = new ArrayList<Person>();

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

  try {

    DocumentBuilder builder = factory.newDocumentBuilder();

    Document dom = builder.parse(inStream);

    Element root = dom.getDocumentElement();

    NodeList items = root.getElementsByTagName("person");//查找所有person節(jié)點(diǎn)

    for (int i = 0; i < items.getLength(); i++) {

      Person person = new Person();

      //得到第一個(gè)person節(jié)點(diǎn)

      Element personNode = (Element) items.item(i);

      //獲取person節(jié)點(diǎn)的id屬性值

      person.setId(new Integer(personNode.getAttribute("id")));

      //獲取person節(jié)點(diǎn)下的所有子節(jié)點(diǎn)(標(biāo)簽之間的空白節(jié)點(diǎn)和name/age元素)

      NodeList childsNodes = personNode.getChildNodes();

      for (int j = 0; j < childsNodes.getLength(); j++) {

        Node node = (Node) childsNodes.item(j); //判斷是否為元素類型

        if(node.getNodeType() == Node.ELEMENT_NODE){

          Element childNode = (Element) node;

          //判斷是否name元素

          if ("name".equals(childNode.getNodeName())) {

            //獲取name元素下Text節(jié)點(diǎn),然后從Text節(jié)點(diǎn)獲取數(shù)據(jù)

            person.setName(childNode.getFirstChild().getNodeValue());

          } else if (“age”.equals(childNode.getNodeName())) {

            person.setAge(new Short(childNode.getFirstChild().getNodeValue()));

          }

        }

      }

      persons.add(person);

    }

    inStream.close();

  } catch (Exception e) {

    e.printStackTrace();

  }

  return persons;

}

3.Pull解析器解析XML文件

Pull解析器的運(yùn)行方式與SAX解析器相似。它提供了類似的事件,如:開始元素和結(jié)束元素事件,使用parser.next()可以進(jìn)入下一個(gè)元素并觸發(fā)相應(yīng)事件。事件將作為數(shù)值代碼被發(fā)送,因此可以使用一個(gè)switch對(duì)感興趣的事件進(jìn)行處理。當(dāng)元素開始解析時(shí),調(diào)用parser.nextText()方法可以獲取下一個(gè)Text類型元素的值。

  //讀取XML

  public static List<Person> readXML(InputStream inStream) {

    XmlPullParser parser = Xml.newPullParser();

    try {

      parser.setInput(inStream, "UTF-8");

      int eventType = parser.getEventType();

      Person currentPerson = null;

      List<Person> persons = null;

      while (eventType != XmlPullParser.END_DOCUMENT) {

        switch (eventType) {

          case XmlPullParser.START_DOCUMENT://文檔開始事件,可以進(jìn)行數(shù)據(jù)初始化處理

            persons = new ArrayList<Person>();

            break;

          case XmlPullParser.START_TAG://開始元素事件

            String name = parser.getName();

            if (name.equalsIgnoreCase("person")) {

              currentPerson = new Person();

              currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));

            } else if (currentPerson != null) {

              if (name.equalsIgnoreCase("name")) {

                currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值

              } else if (name.equalsIgnoreCase("age")) {

                currentPerson.setAge(new Short(parser.nextText()));

              }

            }

            break;

          case XmlPullParser.END_TAG://結(jié)束元素事件

            if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) {

              persons.add(currentPerson);

              currentPerson = null;

            }

            break;

        }

        eventType = parser.next();

      }

      inStream.close();

      return persons;

    } catch (Exception e) {

      e.printStackTrace();

    }

    return null;

  }

  //成XML文件

  //使用Pull解析器生成一個(gè)與itcast.xml文件內(nèi)容相同的myitcast.xml文件。

  public static String writeXML(List<Person> persons, Writer writer){

    XmlSerializer serializer = Xml.newSerializer();

    try {

      serializer.setOutput(writer);

      serializer.startDocument("UTF-8", true);

      //第一個(gè)參數(shù)為命名空間,如果不使用命名空間,可以設(shè)置為null

      serializer.startTag("", "persons");

      for (Person person : persons){

        serializer.startTag("", "person");

        serializer.attribute("", "id", person.getId().toString());

        serializer.startTag("", "name");

        serializer.text(person.getName());

        serializer.endTag("", "name");

        serializer.startTag("", "age");

        serializer.text(person.getAge().toString());

        serializer.endTag("", "age");

        serializer.endTag("", "person");

      }

      serializer.endTag("", "persons");

      serializer.endDocument();

      return writer.toString();

    } catch (Exception e) {

      e.printStackTrace();

    }

    return null;

  }

  //使用代碼如下(生成XML文件):

  File xmlFile = new File("myitcast.xml");

  FileOutputStream outStream = new FileOutputStream(xmlFile);

  OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, "UTF-8");

  BufferedWriter writer = new BufferedWriter(outStreamWriter);

  writeXML(persons, writer);

  writer.flush();

  writer.close();

  //如果只想得到生成的xml內(nèi)容,可以使用StringWriter:

  StringWriter writer = new StringWriter();

  writeXML(persons, writer);

  String content = writer.toString();

4.SAX和PULL使用

區(qū)別為:SAX解析器的工作方式是自動(dòng)將事件推入事件處理器進(jìn)行處理,因此你不能控制事件的處理主動(dòng)結(jié)束;而Pull解析器的工作方式為允許你的應(yīng)用程序代碼主動(dòng)從解析器中獲取事件,正因?yàn)槭侵鲃?dòng)獲取事件,因此可以在滿足了需要的條件后不再獲取事件,結(jié)束解析。

你隨便找個(gè)sax和pull的例子比較一下就可以發(fā)現(xiàn),pull是一個(gè)while循環(huán),隨時(shí)可以跳出,而sax不是,sax是只要解析了,就必須解析完成。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)頁(yè)標(biāo)題:三種解析xml的方式-創(chuàng)新互聯(lián)
URL鏈接:http://muchs.cn/article48/dcjeep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、App開發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司網(wǎng)站營(yíng)銷、服務(wù)器托管、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)