Android Pull解析XML -- Android 学习之路

Pull解析XML

前面总结了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

<?xml version="1.0" encoding="utf-8"?>
<Students>
        <Student id="0">
            <name>张三</name>
            <clazz>13班</clazz>
            <age>17</age>
        </Student>
</Students>

解析代码

List<Student> 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 <Student id='0'>@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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佛系编码i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值