Android XML解析的三種方式

導(dǎo)航

XML的三種解析方式

json全面解析和使用

Gson官方推薦的json解析方式

三種解析XML方法的比較

XML

Android 提供了三種解析XML的方式:SAX(Simple API XML), DOM(Document Object Model), Pull
本文中所用的XML文檔內(nèi)容如下:

<students>
    <student>
        <name sex="man">小明</name>
        <nickName>明明</nickName>
    </student>
    <student>
        <name sex="woman">小紅</name>
        <nickName>紅紅</nickName>
    </student>
    <student>
        <name sex="man">小亮</name>
        <nickName>亮亮</nickName>
    </student>
</students>

第一種、Pull解析方式

1)、創(chuàng)建對應(yīng)XML的Bean對象

public class Student {
    private String name;
    private String sex;
    private String nickName;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}

2)、Pull解析

public class pullxml{
public List<Student> pull2xml(InputStream is) throws Exception {
    List<Student> list = null;
    Student student = null;
    //創(chuàng)建xmlPull解析器
    XmlPullParser parser = Xml.newPullParser();
    ///初始化xmlPull解析器
    parser.setInput(is, "utf-8");
    //讀取文件的類型
    int type = parser.getEventType();
    //無限判斷文件類型進(jìn)行讀取
    while (type != XmlPullParser.END_DOCUMENT) {
        switch (type) {
            //開始標(biāo)簽
            case XmlPullParser.START_TAG:
                if ("students".equals(parser.getName())) {
                    list = new ArrayList<>();
                } else if ("student".equals(parser.getName())) {
                    student = new Student();
                } else if ("name".equals(parser.getName())) {
                    //獲取sex屬性
                    String sex = parser.getAttributeValue(null,"sex");
                    student.setSex(sex);
                    //獲取name值
                    String name = parser.nextText();
                    student.setName(name);
                } else if ("nickName".equals(parser.getName())) {
                    //獲取nickName值
                    String nickName = parser.nextText();
                    student.setNickName(nickName);
                }
                break;
            //結(jié)束標(biāo)簽
            case XmlPullParser.END_TAG:
                if ("student".equals(parser.getName())) {
                    list.add(student);
                }
                break;
        }
        //繼續(xù)往下讀取標(biāo)簽類型
        type = parser.next();
    }
    return list;
}}

調(diào)用的時(shí)候只需傳入xmlData即可

List<student> list=pullxml.pull2xml(getResources().getAssets().open("news.xml"));
tv.setText(list.toString());

第二種、SAX解析方式

SAX(Simple API for XML)解析器是一種基于事件的解析器,事件驅(qū)動的流式解析方式是,從文件的開始順序解析到文檔的結(jié)束,不可暫停或倒退。

  • 優(yōu)點(diǎn):解析速度快,占用內(nèi)存少。非常適合在Android移動設(shè)備中使用。
  • 缺點(diǎn):不會記錄標(biāo)簽的關(guān)系,而要讓你的應(yīng)用程序自己處理,這樣就增加了你程序的負(fù)擔(dān)。
  • 工作原理:對文檔進(jìn)行順序掃描,當(dāng)掃描到文檔(document)開始與結(jié)束、元素(element)開始與結(jié)束、文檔 (document)結(jié)束等地方時(shí)通知事件處理函數(shù),由事件處理函數(shù)做相應(yīng)動作,然后繼續(xù)同樣的掃描,直至文檔結(jié)束。

使用步驟:

1. 新建 ContentHanlder 類繼承 DefaultHandler 類,并重寫父類的五個(gè)方法

  • startDocument(): 開始解析XML時(shí)調(diào)用
  • startElement(): 開始解析某個(gè)結(jié)點(diǎn)時(shí)調(diào)用
  • characters(): 在獲取節(jié)點(diǎn)內(nèi)容時(shí)調(diào)用
  • endElement(): 在完成解析某個(gè)結(jié)點(diǎn)時(shí)調(diào)用
  • endDocument(): 在完成整個(gè)XML解析的時(shí)候調(diào)用

2.創(chuàng)建函數(shù) parseXMLWithSAX

3.調(diào)用函數(shù) parseXMLWithSAX 解析 XML

代碼如下:

新建 ContentHandler 類繼承 DefaultHandler類,重寫五個(gè)父類方法

public class saxxml {
    public static List<student> sax2xml(InputStream is) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        //初始化Sax解析器
        SAXParser sp = spf.newSAXParser();
        //新建解析處理器
        MyHandler handler = new MyHandler();
        //將解析交給處理器
        sp.parse(is, handler);
        //返回List
        return handler.getList();
    }

    public static class MyHandler extends DefaultHandler {

        private List<student> list;
        private student student;
        //用于存儲讀取的臨時(shí)變量
        private String tempString;

        /**
         * 解析到文檔開始調(diào)用,一般做初始化操作
         *
         * @throws SAXException
         */
        @Override
        public void startDocument() throws SAXException {
            list = new ArrayList<>();
            super.startDocument();
        }

        /**
         * 解析到文檔末尾調(diào)用,一般做回收操作
         *
         * @throws SAXException
         */
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }

        /**
         * 每讀到一個(gè)元素就調(diào)用該方法
         *
         * @param uri
         * @param localName
         * @param qName
         * @param attributes
         * @throws SAXException
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if ("student".equals(qName)) {
                //讀到student標(biāo)簽
                student = new student();
            } else if ("name".equals(qName)) {
                //獲取name里面的屬性
                String sex = attributes.getValue("sex");
                System.out.println("sex-----"+sex);
                student.setSex(sex);
            }
            super.startElement(uri, localName, qName, attributes);
        }

        /**
         * 讀到元素的結(jié)尾調(diào)用
         *
         * @param uri
         * @param localName
         * @param qName
         * @throws SAXException
         */
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("student".equals(qName)) {
                list.add(student);
            }
            if ("name".equals(qName)) {
                student.setName(tempString);
            } else if ("nickName".equals(qName)) {
                student.setNiceName(tempString);
            }
            super.endElement(uri, localName, qName);
        }

        /**
         * 讀到屬性內(nèi)容調(diào)用
         *
         * @param ch
         * @param start
         * @param length
         * @throws SAXException
         */
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            tempString = new String(ch, start, length);

            super.characters(ch, start, length);
        }

        /**
         * 獲取該List
         *
         * @return
         */
        public List<student> getList() {
            return list;
        }
    }
}

調(diào)用的時(shí)候只需傳入xmlData即可

List<student> list=saxxml.sax2xml(getResources().getAssets().open("news.xml"));
tv.setText(list.toString());

【注:在Android API中,另外提供了Android.util.Xml類,同樣可以解析XML文件,使用方法類似SAX,也都需編寫Handler來處理XML的解析,但是在使用上卻比SAX來得簡單 ,如下所示:
以android.util.XML實(shí)現(xiàn)XML解析:
MyHandler myHandler=new MyHandler0;
android.util.Xm1.parse(ur1.openC0nnection().getlnputStream0,Xm1.Encoding.UTF-8,myHandler);】

第三種、Dom解析方式

Paste_Image.png

1)、創(chuàng)建對應(yīng)XML的Bean對象

和第一種一樣這里就不貼了

2)、Dom解析

public List<Student> dom2xml(InputStream is) throws Exception {
    //一系列的初始化
    List<Student> list = new ArrayList<>();
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    //獲得Document對象
    Document document = builder.parse(is);
    //獲得student的List
    NodeList studentList = document.getElementsByTagName("student");
    //遍歷student標(biāo)簽
    for (int i = 0; i < studentList.getLength(); i++) {
        //獲得student標(biāo)簽
        Node node_student = studentList.item(i);
        //獲得student標(biāo)簽里面的標(biāo)簽
        NodeList childNodes = node_student.getChildNodes();
        //新建student對象
        Student student = new Student();
        //遍歷student標(biāo)簽里面的標(biāo)簽
        for (int j = 0; j < childNodes.getLength(); j++) {
            //獲得name和nickName標(biāo)簽
            Node childNode = childNodes.item(j);
            //判斷是name還是nickName
            if ("name".equals(childNode.getNodeName())) {
                String name = childNode.getTextContent();
                student.setName(name);
                //獲取name的屬性
                NamedNodeMap nnm = childNode.getAttributes();
                //獲取sex屬性,由于只有一個(gè)屬性,所以取0
                Node n = nnm.item(0);
                student.setSex(n.getTextContent());
            } else if ("nickName".equals(childNode.getNodeName())) {
                String nickName = childNode.getTextContent();
                student.setNickName(nickName);
            }
        }
        //加到List中
        list.add(student);
    }
    return list;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,745評論 25 709
  • 一、緒論 上周工作需要了解項(xiàng)目的一些大體內(nèi)容,結(jié)果在xml解析這一塊看的迷迷糊糊的,所以在這里把學(xué)習(xí)到xm...
    cao健強(qiáng)閱讀 4,516評論 1 7
  • 一、DOM解析XML 我們首先來看看DOM(Document Object Model)這種方式解析xml,通過D...
    小董666閱讀 405評論 0 1
  • 當(dāng)我說到禁忌字母的時(shí)候,你想到了哪兩個(gè)? 是的,別覺得自己想歪了,我說的就是你想到的。 感覺是一種很奇怪的東西,無...
    千裳閱讀 715評論 0 0
  • 那天是愚人節(jié)。 跨進(jìn)院子,眼前是這樣的景象,立馬呆住… 安安,5歲半,是姊髻服裝結(jié)構(gòu)設(shè)計(jì)師佳妮家的寶貝。他告訴媽媽...
    甘棠子子閱讀 965評論 2 4

友情鏈接更多精彩內(nèi)容