【Android學習】XML文本的三種解析方式(經過搭建本地的Web項目提供XML文件)

XML爲一種可擴展的標記語言,是一種簡單的數據存儲語言,使用一系列簡單的標記來描述。java

1、SAX解析

  即Simple API for XML,以事件的形式通知程序,對Xml進行解析。node

  一、首先在Web項目中發佈一個XML文檔,名字爲persons.xml,具體內容爲: 服務器

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="1">
        <name>周杰倫</name>
        <age>20</age>
    </person>
    <person id="2">
        <name>小明</name>
        <age>21</age>
    </person>

</persons>

  二、SAX解析的流程主要以下:dom

  

  經過建立SAXParserFactory對象得到一個實例,而後再經過工廠得到一個SaxParser,依靠SaxParser的parse方法,完成解析,其中parse方法的參數爲一個InputStream類和一個DefaultHandler類,defaultHandler需         要重寫ide

    SAXParserFactory spf = SAXParserFactory.newInstance();
       SAXParser parse = spf.newSAXParser();
       Myhandler handler = new Myhandler("person");
       parse.parse(is, handler);
       list = handler.getList();

  

  三、重寫處理類DefaultHandler。post

  

  


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class Myhandler extends DefaultHandler {

    List<HashMap<String, String>> list = null;// 存儲全部的解析對象
    String currentTag = null; // 正在解析的標籤
    String currentValue = null; // 正在解析元素的值
    String nodename = null; // 正在解析節點名稱
    HashMap<String, String> map = null;// 存儲單個解析的完整對象

    public Myhandler(String nodename) {
        this.nodename = nodename;
    }

    public List<HashMap<String, String>> getList() {
        return list;
    }

    @Override
    // 讀到第一個開始標籤的時候觸發
    public void startDocument() throws SAXException {

        list = new ArrayList<HashMap<String, String>>();
    }

    @Override
    // 當遇到所要解析的節點名稱時觸發
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {

        if (qName.equals(nodename)) {
            map = new HashMap<String, String>();

        }

        if (attributes != null && map != null) {
            for (int i = 0; i < attributes.getLength(); i++) {
                map.put(attributes.getQName(i), attributes.getValue(i));
            }
        }

        currentTag = qName;

    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (qName.equals(nodename)) {
            list.add(map);
            map = null;
        }
        super.endElement(uri, localName, qName);
    }

    @Override
    // 處理xml文件讀取到的內容
    public void characters(char[] ch, int start, int length)
            throws SAXException {

        if (currentTag != null && map != null) {
            currentValue = new String(ch, start, length);
            if (currentValue != null && !currentValue.trim().equals("")
                    && !currentValue.trim().equals("\n")) {
                map.put(currentTag, currentValue);
            }

        }

        currentTag = null;
        currentValue = null;
    }

}

  

  

  

  四、經過自定義的HttpUtils類,從服務器獲取數據,以流的形式返回,也就是XML文檔的輸入流,這裏再也不給出,關於得到服務器數據的三種方式下次會下次更新。ui

 

  五、最後經過返回的List<Map<String,String>> 得到了XML文檔的所須要的內容,須要提到的是,我在這裏是須要解析person節點,因而只有qName等於person時候纔會開始解析。this

 

2、PULL解析

  相似於SAX方式,程序以「拉取」的方式對Xml進行解析。spa

  一、與SAX解析相似,但比SAX解析容易,須要JAR包,下載地址:code

  二、首先經過XMLPullFactory建立一個工廠,而後再由工廠建立一個XMLPullParser對象,由對象進行相關處理。

  三、經過對eventType進行XML文件的節點解析,得到數據,並存放在List中進行返回。

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

public class PullXmlHandler {

    public static List<Person> parseXml(InputStream is, String encode)
            throws Exception {
        List<Person> list = null;
        Person p = null;
        try {
            XmlPullParserFactory xmlPullF = XmlPullParserFactory.newInstance();
            XmlPullParser parser = xmlPullF.newPullParser();
            parser.setInput(is, encode);
            int eventType = parser.getEventType();
  
        
//若是還沒到文檔結束節點就一直循環
while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: list = new ArrayList
<Person>(); break; case XmlPullParser.START_TAG: if (parser.getName().equals("person")) { p = new Person(); if (parser.getAttributeCount() != 0) { p.setId(parser.getAttributeValue(0)); } } else if (parser.getName().equals("name")) { p.setName(parser.nextText()); } else if (parser.getName().equals("age")) { p.setAge(parser.nextText()); } break; case XmlPullParser.END_TAG: if (parser.getName().equals("person")) { list.add(p); p = null; } break; default: break; }         //進行下次循環
  eventType = parser.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } }
 

3、DOM解析

  「文檔對象模型」方式,解析完的Xml將生成一個樹狀結構的對象。

  一、DOM解析相對前兩種比較麻煩,代碼以下:

  

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.xml.httputils.http_post;

public class DomService {

    public DomService() {
    }

    public static List<Person> parseXML(InputStream is) throws Exception {
        List<Person> list = new ArrayList<Person>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(is);
        // 得到節點
        Element element = document.getDocumentElement();
        NodeList nodeList = element.getElementsByTagName("person");
        for (int i = 0; i < nodeList.getLength(); i++) {
            Element personElement = (Element) nodeList.item(i);
            Person p = new Person();
            p.setId(personElement.getAttribute("id"));
            NodeList personList = personElement.getChildNodes();
            for (int j = 0; j < personList.getLength(); j++) {
                if (personList.item(j).getNodeType() == Node.ELEMENT_NODE) {
                    if ("name".equals(personList.item(j).getNodeName())) {
                        p.setName(personList.item(j).getFirstChild()
                                .getNodeValue());
                    } else if ("age".equals(personList.item(j).getNodeName())) {
                        p.setAge(personList.item(j).getFirstChild()
                                .getNodeValue());
                    }
                }
            }
            list.add(p);
        }
        return list;

    }

    public static void main(String[] args) throws Exception {
        DomService dom = new DomService();
        List<Person> ps = dom.parseXML(http_post.getXMLStream());
        for (Person p : ps) {
            System.out.println(p);
        }
    }
}

 

總結:

  對於小內存的設備,尤爲是Android設備,使用PULL解析或者SAX解析遠優於DOM解析。

相關文章
相關標籤/搜索