Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android SAX解析XML文檔 -- Android 學習之路

Android SAX解析XML文檔 -- Android 學習之路

編輯:關於Android編程

SAX解析XML

最近用到了XML數據 ,今天分享一下我對SAX的理解

原理 實例
自定義Handler 繼承DefaultHandler Handler執行順序各方法參數講解 SaxParse的創建 設置解析內容 開始解析

原理

sax 是基於事件驅動。那麼什麼是事件驅動呢(請自行百度)簡單點說 就是觸發一個事件 去執行某些操作;

sax在解析XML時 是邊讀取邊解析,不會將整個文檔加載到內存中。而是讀到一個元素解析一個元素,和上下的元素是關聯不上的,占用內存較小。這也是非常適合Android這種內存較小的嵌入式設備內存的原因;

sax在讀取文檔的時候激活一系列的事件並執行一些操作。

在開始讀取文檔的時候觸發 startDocument() ;

讀取到一個元素觸發 startElement();

讀取文本 觸發characters(); ps:即使是讀取到換行符也會觸發

元素讀取完畢 觸發 endElement();

讀取完整個文檔觸發 endDocument();

上述事件 基本就把xml文檔讀取完畢了,這些方法在DefaultHandle中已經封裝好了,我們做的就是重寫這些方法就可以了

貼代碼

student XML文件



        
            張三
            13班
            17
        

創建 StudentHandler 繼承自 DefaultHandler

package com.skymxc.demo.parsexml;

import android.text.TextUtils;
import android.util.Log;

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

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

/**
 * Created by sky-mxc
 */
public class StudentHandler extends DefaultHandler {

    private List students;
    private Student student;
    private String tag;     //記錄讀取到的元素的名字



    @Override
    public void startDocument() throws SAXException {
        Log.e("Tag","=======startDocument()========");
        students = new ArrayList<>();
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        Log.e("Tag","=======endDocument()========");
    }

    /**
     *
     * @param uri 明明空間的uri
     * @param localName 不帶前綴的元素名字
     * @param qName 帶有前綴的元素名
     * @param attributes 屬性
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        Log.e("Tag","==========startElement()==========="+localName);
        Log.e("Tag","===startElement():uri======"+uri);
        Log.e("Tag","===startElement():localName======"+localName);
        Log.e("Tag","===startElement():qName======"+qName);

        switch (localName){
            case "Student":         //student元素
                student = new Student();
                int id = Integer.parseInt(attributes.getValue("id"));   //獲取到屬性id的值
                student.setId(id);
                break;
            default:
                tag=localName;//除了 student元素 其他元素都要讀取文本 characters()無法獲取元素名字
                break;
        }

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        Log.e("Tag","==========endElement()==========="+localName);
        switch (localName){
            case "Student":
                students.add(student);
                break;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        Log.e("Tag","==========characters()===========");
        Log.e("Tag","======start:"+start);
        Log.e("Tag","======length:"+length);

        //將字符轉為字符串
        String text = new String(ch,start,length).trim();
        Log.e("Tag","====當前元素:"+tag+"===文本值:"+text);
        //排除無效字符 會讀取到一些換行符
        if (TextUtils.isEmpty(text)) return;
        if (student == null) return;
        switch (tag){
            case "name":
                student.setName(text);
                break;
            case "age":
                int age = Integer.parseInt(text);
                student.setAge(age);
                break;
            case "clazz":
                student.setClazz(text);
                break;
        }
    }

    public List getStudents() {
        return students;
    }
}

Handler中的執行過程解析 讀取過程如下,可以看出 就算根節點沒有文本也觸發了characters() 因為會讀取換行符 所以慎重處理

E/Tag: =======startDocument()========
E/Tag: ==========startElement()===========Students
E/Tag: ==========characters()===========
E/Tag: ==========characters()===========
E/Tag: ==========startElement()===========Student
E/Tag: ==========characters()===========
E/Tag: ==========characters()===========
E/Tag: ==========startElement()===========name
E/Tag: ==========characters()===========
E/Tag: ==========endElement()===========name
E/Tag: ==========characters()===========
E/Tag: ==========characters()===========
E/Tag: ==========startElement()===========clazz
E/Tag: ==========characters()===========
E/Tag: ==========endElement()===========clazz
E/Tag: ==========characters()===========
E/Tag: ==========characters()===========
E/Tag: ==========startElement()===========age
E/Tag: ==========characters()===========
E/Tag: ==========endElement()===========age
E/Tag: ==========characters()===========
E/Tag: ==========characters()===========
E/Tag: ==========endElement()===========Student
E/Tag: ==========characters()===========
E/Tag: ==========endElement()===========Students
E/Tag: =======endDocument()========

startElement() 參數如下 xml 文件中並沒有定義 命名空間 和任何前綴
uri :為空
qName :也是元素的名字並沒有帶有前綴
localName: 當前元素的名字

E/Tag: ===startElement():uri======
E/Tag: ===startElement():localName======Student
E/Tag: ===startElement():qName======Student
E/Tag: ==========characters()===========

characters()參數如下
start :開始下標
length :長度

 E/Tag: ==========characters()===========
 E/Tag: ======start:0
 E/Tag: ======length:3
 E/Tag: ====當前元素:clazz===文本值:13班

創建SAXParse 設置解析內容

 SAXParserFactory factory = SAXParserFactory.newInstance();
                StudentHandler handler = new StudentHandler();
                try {
                    SAXParser parser = factory.newSAXParser();
                    parser.parse(getAssets().open("students.xml"),handler);
                    Log.e("Tag","===Size:"+handler.getStudents().size());
                    for (Student stu :handler.getStudents()){
                        Log.e("Tag","==Name:"+stu.getName()+"===Age:"+stu.getAge()+"====Clazz:"+stu.getClazz()+"==id:"+stu.getId());
                    }
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

讀取結果

 E/Tag: ==Name:張三===Age:17====Clazz:13班==id:0

對於SAX的理解就這些了
為什麼只有深夜 才有感覺呢,唉…..發愁

github地址 :https://github.com/sky-mxc/AndroidDemo/tree/master/parsexml

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved