安卓使用pull解析器解析xml

来源:互联网 发布:淘宝女士秋季连衣裙 编辑:程序博客网 时间:2024/04/29 15:18

 XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Xmlpull比Sax更简明,而且不需要扫描完整个流。


概述:

PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。

PULL 的工作原理:

XML pull提供了开始元素和结束元素。当某个元素开始时,可以调用parsernextTextXML文档中提取所有字符数据。当解析到一个文档结束时,自动生成EndDocument事件。

常用的XML pull的接口和类:

XmlPullParser该解析器是一个在org.xmlpull.v1中定义的解析功能的接口。

XmlSerializer它是一个接口,定义了XML信息集的序列。

XmlPullParserFactory这个类用于在XMPULL V1 API中创建XML Pull解析器。

XmlPullParserException抛出单一的XML pull解析器相关的错误。

PULL解析器的运行方式和SAX类似,都是基于事件的模式。

不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码:

读取到xml声明返回 START_DOCUMENT; 结束返回 END_DOCUMENT ; 开始标签返回 START_TAG;

结束标签返回 END_TAG; 文本返回 TEXT。

几种解析技术的比较与总结: 
对于Android的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。

DOM在处理XML文件时,将XML文件解析成树状结构并放入内存中进行处理。当XML文件较小时,我们可以选DOM,因为它简单、直观。

SAX则是以事件作为解析XML文件的模式,它将XML文件转化成一系列的事件,由不同的事件处理器来决定如何处理。XML文件较大时,选择SAX技术是比较合理的。虽然代码量有些大,但是它不需要将所有的XML文件加载到内存中。这样对于有限的Android内存更有效,而且Android提供了一种传统的SAX使用方法以及一个便捷的SAX包装器。 使用AndroidutilXml类,从示例中可以看出,会比使用 SAX来得简单。

XML pull解析并未像SAX解析那样监听元素的结束,而是在开始处完成了大部分处理。这有利于提早读取XML文件,可以极大的减少解析时间,这种优化对于连接速度较漫的移动设备而言尤为重要。对于XML文档较大但只需要文档的一部分时,XML Pull解析器则是更为有效的方法。

下面附上一个小的DEMO案例:

要解析的xml文档:

person.xml

<persons>    <person personid="1">        <name>谢栋</name>        <sex>男</sex>        <job>开发</job>        <age>12</age>        <phone>138****5227</phone>    </person>    <person personid="2">        <name>洛希</name>        <sex>男</sex>        <age>17</age>        <phone>178****5227</phone>        <job>编辑</job>    </person></persons>


pull解析功能代码:

public class Xml_Test extends ActionBarActivity {    private String TAG="xiedong";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_xml__test);        ArrayList<Person> person= parse();       //快速插入for循环 alt+shift+ctrl+j        Log.i(TAG,person.size()+"dd");//        for (int i = 0; i < person.size(); i++) {////            System.out.print(person.toString());//            Log.i("x",person.get(i).toString());//        }        Log.i(TAG,person.get(0).toString());        Log.i(TAG,person.get(1).toString());//        for (Person p: person ){//            Log.i("xie",p.toString());////        }    }    private ArrayList<Person> parse() {        ArrayList <Person> list=new ArrayList<>();        Person p = null;        try {            //把要解析的xml文件包装成输入流            InputStream in = getResources().openRawResource(R.raw.persons);            XmlPullParser pullParser = Xml.newPullParser();            //关联要解析的xml文件,不指定编码格式的话,需要把文件包装成字符输入流//            InputStreamReader isr = new InputStreamReader(getResources().openRawResource(R.raw.persons));//            pullParser.setInput(isr);            //关联要解析的xml文件,并指定编码格式            pullParser.setInput(in,"utf-8");            //获取当前的事件类型           int eventType = pullParser.getEventType();            while(eventType!=XmlPullParser.END_DOCUMENT){                String tag =pullParser.getName();                switch (eventType){                    //得到跟节点,做一些初始化操作                    case XmlPullParser.START_DOCUMENT:////                        list=new ArrayList<Person>();//                        p =new Person();     //Person实例化位置不当,导致一直出现重复数据,(测试的时候打印两条第二个节点的数据,第一个节点被覆盖,是因为Person对象实例化的位置不对,导致只new出来一个person对象,所以第一条数据在第二条数据加载出来的时候被覆盖掉了)                        break;                    //得到子标签开始解析                    case XmlPullParser.START_TAG :                        if("person".equals(tag)){                            //每次开始解析一个一个对象都需要重新实例化一个Person对象,并且需要注意Person实例化的位置                            p=new Person();                            p.setId(Integer.parseInt(pullParser.getAttributeValue(null,"personid")));                        }else if("name".equals(tag)){                            p.setName(pullParser.nextText());                        }else if("sex".equals(tag)){                            p.setSex(pullParser.nextText());                        }else if("job".equals(tag)){                            p.setJob(pullParser.nextText());                        }else if("age".equals(tag)){//                            Log.i("xiedong",pullParser.nextText());                            p.setAge(Integer.parseInt(pullParser.nextText()));                        }else if("phone".equals(tag)){//                            Log.i("xiedong",pullParser.nextText());                            p.setPhone(pullParser.nextText());                        }//                        Person{name='null', sex='null', phone='138****5227', age=0, job='null', id=0}                        break;                    //解析到子节点末尾,把解析完的数据添加到List集合中去                    case XmlPullParser.END_TAG:                        if("person".equals(pullParser.getName())) {                            list.add(p);                          Log.i("xiedo",list.toString());                        }                        break;                }                //解析下一个事件类型(当前解析位置结 束,指向下一个位置)                eventType = pullParser.next();            }        } catch (XmlPullParserException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return list;    }}

用于封装person的实体类

person.java

package bean;/** * Created by 谢栋 on 2016/9/25. */public class Person {    private String name;    private String sex;    private String phone;    private int age;    private String job;    private int id;    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 getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getJob() {        return job;    }    public void setJob(String job) {        this.job = job;    }    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @Override    public String toString() {        return "Person{" +                "name='" + name + '\'' +                ", sex='" + sex + '\'' +                ", phone='" + phone + '\'' +                ", age=" + age +                ", job='" + job + '\'' +                ", id=" + id +                '}';    }}

经过xml解析后在控制台打印的消息如下
 Person{name='谢栋', sex='男', phone='138****5227', age=12, job='开发', id=1}

 Person{name='洛希', sex='男', phone='178****5227', age=17, job='编辑', id=2}

1 0
原创粉丝点击