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

Android Pull解析XML -- Android 學習之路

編輯:關於Android編程

前面總結了SAX解析的理解 這裡吧PullParse 的理解也分享一下吧

原理分析 常用方法 使用步驟 實例(貼代碼) 讀取過程分析 使用注意的點

我理解的原理

pull解析也是 基於事件驅動的,變讀取邊解析,不會將整個文檔加載進內存
pullParser在讀取時設立了四個事件,這四個事件,兩個是文檔開始和結束,兩個是元素開始和結束 ,當pullParser開始讀取後,就是一直讀取元素,結束讀取元素的過程
XmlPullParser.START_DOCUMNET 開始讀取文檔事件
XmlPullParser.START_TAG 開始讀取標簽(元素)事件
XmlPullParser.END_TAG 標簽讀取結束事件
XmlPullParser.END_DOCUMNET 文檔讀取結束事件

通過getEventType()開始讀取,並返回現在的事件的類型(XmlPullParser.START_DOCUMNET)
然後依次向下讀取
觸發讀取標簽事件(XmlPullParser.START_TAG)
標簽讀取結束事件,文檔讀取結束事件
四個事件中 START_DOCUMNET 和END_DOCUMNET只會觸發一次,
在讀取的過程中,是在START_TAG和END_TAG之間來回循環的,
pullParser每觸發一次事件之後就會 暫停,需要我們手動去觸發我們可以通過next()方法來繼續讀取下一個 並返回下一個事件的類型
這些就是我理解的了


常用的方法

setInput(InputStream is,String s) ,setInput(Reader reader) :設置解析內容 int getEventType() :開始讀取並返回事件類型 int next() :開始下一個事件,返回事件類型 String getName() :正在讀取的元素名字 String getAttributeValue(String ,String) :獲取屬性的值 參數1 是空間名字沒有的話就放“”參數2是屬性的名字 String nextText() :此元素內的文本 String getAttributeXXX() :都是關於屬性的操作

使用步驟:

得到解析器 工廠 XmlPullParserFactory

//0.得到解析器工廠實例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

創建解析器利用解析器工廠 XmlPullParser

//1.創建解析器 利用解析器工廠
XmlPullParser pullParser = factory.newPullParser();
//  Xml.newPullParser(); Android中的pull方法

設置解析內容 (setInput())可以接受的兩種 內容:
字符流Reader和字節流InputStream ,字節流需要指定字符編碼 一般是utf-8

//2.設置解析內容
pullParser.setInput(getAssets().open("students.xml"),"utf-8");

開始解析:

int type = pullParser.getEventType();//開始解析並返回事件類型

寫一個例子

students.xml



        
            張三
            13班
            17
        

解析代碼

List students =null;
Student student =null;
//得到解析工廠
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//創建pullParser
XmlPullParser parser = factory.newPullParser();
//設置解析內容 指定字符編碼 utf-8
parser.setInput(getAssets().open("students.xml"),"utf-8");
//開始解析並得到狀態碼
int type = parser.getEventType();
//循環讀取解析
while (type!=XmlPullParser.END_DOCUMENT){
    switch (type){
        case XmlPullParser.START_DOCUMENT:
            Log.e("Tag","======START_DOCUMENT=========");
            students = new ArrayList<>();
            break;
        case XmlPullParser.START_TAG:
            Log.e("Tag","======START_TAG========="+parser.getName());
            switch (parser.getName()){
                case "Student":
                    student = new Student();
                    int id = Integer.parseInt(parser.getAttributeValue("","id"));
                    Log.e("Tag","=======讀取屬性id:======"+id);
                    student.setId(id);
                    break;
                case "name":
                    String text = parser.nextText();
                    Log.e("Tag","======讀取文本======"+text);
                    student.setName(text);
                    break;
                case "age":
                    int age = Integer.parseInt(parser.nextText());
                    Log.e("Tag","======讀取文本======"+age);
                    student.setAge(age);
                    break;
                case "clazz":
                     text = parser.nextText();
                    Log.e("Tag","======讀取文本======"+text);
                    student.setClazz(text);
                    break;
            }
            break;
        case XmlPullParser.END_TAG:
            Log.e("Tag","======END_TAG========="+parser.getName());
            switch (parser.getName()){
                case "Student":
                    students.add(student);
                    break;
            }
            break;
        case XmlPullParser.END_DOCUMENT:
            Log.e("Tag","======END_DOCUMENT=========");
            break;
    }
    //繼續讀取 並返回狀態碼
    type = parser.next();
}

for (Student stu :students){
    Log.e("Tag","==Name:"+stu.getName()+"===Age:"+stu.getAge()+"====Clazz:"+stu.getClazz()+"==id:"+stu.getId());
}

結果

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

讀取順序查看

通過Log日志可以看出 凡是含有文本的元素都沒有觸發 END_TAG

 E/Tag: ======START_DOCUMENT=========
 E/Tag: ======START_TAG=========Students
 E/Tag: ======START_TAG=========Student
 E/Tag: =======讀取屬性id:======0
 E/Tag: ======START_TAG=========name
 E/Tag: ======讀取文本======張三
 E/Tag: ======START_TAG=========clazz
 E/Tag: ======讀取文本======13班
 E/Tag: ======START_TAG=========age
 E/Tag: ======讀取文本======17
 E/Tag: ======END_TAG=========Student
 E/Tag: ======END_TAG=========Students

使用注意

pull解析不會讀取換行符之類的文本 如果你當前元素下沒有文本是不能使用 parser.nextText() 方法,否則會出現錯誤的,所以讀取文本或者屬性要注意了,沒有判斷當前元素文本就直接讀取文本會出現以下錯誤:
Log.e("Tag","======START_TAG========="+parser.getName());
String text = parser.nextText();    //直接去讀取文本
Log.e("Tag","==================="+text);

出現的異常

E/Tag: ======START_DOCUMENT=========
E/Tag: ======START_TAG=========Students
W/System.err: org.xmlpull.v1.XmlPullParserException: END_TAG expected (position:START_TAG @3:25 in java.io.InputStreamReader@5355f8d0) 
W/System.err:     at org.kxml2.io.KXmlParser.nextText(KXmlParser.java:2067)
W/System.err:     at com.skymxc.demo.parsexml.MainActivity.executePull(MainActivity.java:83)
W/System.err:     at com.skymxc.demo.parsexml.MainActivity.onClick(MainActivity.java:56)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
W/System.err:     at android.view.View.performClick(View.java:4084)
W/System.err:     at android.view.View$PerformClick.run(View.java:16966)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:615)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err:     at android.os.Looper.loop(Looper.java:137)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4745)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
W/System.err:     at dalvik.system.NativeStart.main(Native Method)

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

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