浅析PULL解析

原创 2015年07月10日 13:54:00

浅析PULL解析

1. 基本介绍

PULL方式解析XML是在Android中极力推荐使用的一种解析XML的方式,但PULL解析除了在Android中可以使用外,在JavaSE中仍然可以使用。

在JavaSE中,我们要使用PULL解析XML,首先得获取XmlPull所需要的类库及依赖类库:

lib

类库Jar包下载地址:

http://www.findjar.com/jar/xmlpull/xmlpull/1.1.3.4a/xmlpull-1.1.3.4a.jar.html

http://sourceforge.net/projects/kxml/

2. PULL解析

在XmlPull的API类库中,我们可以看到,其实XmlPull非常简单,主要包含了两个接口,一个类,一个异常,实际我们在使用过程中,用得最多的是XmlPullParser接口中的方法。

PULL解析简单易用,因为XmlPullParser接口中只需要调用一个next方法就可以获取下一个事件类型,并且只有五种事件类型:

  1. START_DOCUMENT:文档开始,解析器还未读取到任何输入的时候
  2. START_TAG:解析到开始标签
  3. TEXT:解析到文本节点
  4. END_TAG:解析到结束标签
  5. END_DOCUMENT:文档结束

2.1 XmlPullParser常用方法

// 获取指定索引属性的属性值,索引从0开始
public abstract String getAttributeValue (int index);

// 返回当前事件类型
public abstract int getEventType ();

// 返回当前事件类型的内容字符串形式
public abstract String getText ();

// 获取下一个解析事件类型
public abstract int next ();

// 当前是开始标签,如果下一个元素为文本,则返回该文本字符串,
// 如果下一个元素是结束标签,则返回空字符串,其它情况将抛出异常
public abstract String nextText ();

// 设置即将被解析的输入流
public abstract void setInput (InputStream inputStream, String inputEncoding);

2.2 解析步骤

下面我们一步一步地实现PULL解析。

首先,我们需要创建一个解析器对象,解析器对象的创建是通过解析器工厂对象获取到的:

// 创建解析器工厂对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 从工厂中获取解析器对象
XmlPullParser parser = factory.newPullParser();

接下来我们设置解析器的输入流:

// 设置解析器输入流
parser.setInput(in, encode);

接着我们就可以开始解析xml了。

在PULL解析的典型应用中,我们一般会重复调用next()方法获取下一个事件类型,然后处理,直到事件类型为END_DOCUMENT为止。

/* 解析 */
// 获取解析到的事件类型
int eventType = parser.getEventType();
// 未解析到文档结尾,则循环解析
while (eventType != XmlPullParser.END_DOCUMENT) {
    switch (eventType) {
    case XmlPullParser.START_DOCUMENT: // 文档开始事件
        emps = new ArrayList<Employee>();
        break;
    case XmlPullParser.START_TAG: // 开始标签事件
        String nodeName = parser.getName().trim();
        if ("employee".equals(nodeName)) { // employee节点
            emp = new Employee();
            // 该节点有id属性,则获取id属性
            int id = Integer.parseInt(parser.getAttributeValue(null, "id"));
            emp.setId(id);
        } else if ("name".equals(nodeName)) {
            String name = parser.nextText().trim();
            emp.setName(name);
        } else if ("age".equals(nodeName)) {
            int age = Integer.parseInt(parser.nextText().trim());
            emp.setAge(age);
        } else if ("address".equals(nodeName)) {
            String address = parser.nextText();
            emp.setAddress(address);
        }
        break;
    case XmlPullParser.END_TAG: // 结束标签事件
        if ("employee".equals(parser.getName().trim())) {
            emps.add(emp);
            emp = null;
        }
        break;
    }

    eventType = parser.next(); // 切换到下一个解析事件
}

完整示例:

xml文件:

<employees>
    <employee id="1">
        <name>小明</name>
        <age>29</age>
        <address>四川成都</address>
    </employee>
    <employee id="2">
        <name>老骆</name>
        <age>35</age>
        <address>四川成都</address>
    </employee>
</employees>

员工类:

package com.demo5;

/**
 * 员工类
 * 
 * @author 小明
 *
 */
public class Employee {

    private int id;
    private String name;
    private int age;
    private String address;

    public Employee() {
        super();
    }

    public Employee(int id, String name, int age, String address) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", age=" + age
                + ", address=" + address + "]";
    }

}

解析服务类:

package com.demo5;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

/**
 * 服务类
 * @author 小明
 *
 */
public class Service {

    /**
     * 读取XML解析
     * 
     * @param in
     *            xml文件流
     * @param encode
     *            文件编码
     * @return
     */
    public static List<Employee> readXml(InputStream in, String encode) {
        List<Employee> emps = null;
        Employee emp = null;
        try {
            // 创建解析器工厂对象
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            // 从工厂中获取解析器对象
            XmlPullParser parser = factory.newPullParser();
            // 设置解析器输入
            parser.setInput(in, encode);

            /* 解析 */
            // 获取解析到的事件类型
            int eventType = parser.getEventType();
            // 未解析到文档结尾,则循环解析
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT: // 文档开始事件
                    // 创建List集合对象
                    emps = new ArrayList<Employee>();
                    break;
                case XmlPullParser.START_TAG: // 标签开始事件
                    String nodeName = parser.getName().trim(); // 节点名称
                    if ("employee".equals(nodeName)) { // employee节点
                        emp = new Employee(); // 创建员工对象
                        // 该节点有id属性,则获取id属性
                        int id = Integer.parseInt(parser.getAttributeValue(
                                null, "id"));
                        emp.setId(id);
                    } else if ("name".equals(nodeName)) { // name节点
                        String name = parser.nextText().trim();
                        emp.setName(name);
                    } else if ("age".equals(nodeName)) { // age节点
                        int age = Integer.parseInt(parser.nextText().trim());
                        emp.setAge(age);
                    } else if ("address".equals(nodeName)) { // address节点
                        String address = parser.nextText();
                        emp.setAddress(address);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if ("employee".equals(parser.getName().trim())) {
                        emps.add(emp);
                        emp = null;
                    }
                    break;
                }

                eventType = parser.next(); // 切换到下一个解析事件
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return emps;
    }
}

测试类:

package com.demo5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

public class Test {

    public static void main(String[] args) throws FileNotFoundException {
        InputStream in = new FileInputStream("demo.xml");
        List<Employee> list = Service.readXml(in, "utf-8");

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android视图绘制流程完全解析,带你一步步深入了解View(二)

在上一篇文章中,我带着大家一起剖析了一下LayoutInflater的工作原理,可以算是对View进行深入了解的第一步吧。那么本篇文章中,我们将继续对View进行深入探究,看一看它的绘制流程到底是什么...

XML PULL解析

Pull和Sax类似,都是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Pull和Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形...

Android视图状态及重绘流程分析,带你一步步深入了解View(三)

在前面一篇文章中,我和大家一起从源码的层面上分析了视图的绘制流程,了解了视图绘制流程中onMeasure、onLayout、onDraw这三个最重要步骤的工作原理,那么今天我们将继续对View进行深入...

XML概述以及Pull解析详解

XML概述以及Pull解析详解 ONE Goal ,ONE Passion ! 做Android开发最多的都是json.而且解析xml都用Xstream,慢慢地xml的手动解析都快忘记了.概述:XML...

Android之PULL解析XML

今天我们一起通过一个小例子来学习一下使用PULL解析器解析XML文件。 (1)首先我们放一个文件名为beauties.xml的XML文件到assets目录下,文件内容如下: ...

历久而新,我的新书《第二行代码》已出版!

《第二行代码》中的内容我相信很多人都会非常感兴趣,因为里面确实加入了很多很新的知识。略粗概括一下的话,新增内容就包括有Android Studio、Gradle、Material Design、运行时...

Android LayoutInflater原理分析,带你一步步深入了解View(一)

有不少朋友跟我反应,都希望我可以写一篇关于View的文章,讲一讲View的工作原理以及自定义View的方法。没错,承诺过的文章我是一定要兑现的,而且在View这个话题上我还准备多写几篇,尽量能将这个知...

春亭装潢·小春课题——泥水工程

小春课堂·小春图解screen.width-200){this.width=screen.width-200;}" border="0" />厨卫间的防水,春亭所使用的一律是专业防水剂,不正规公司会用...

Android产品研发(十)-->尽量不使用静态变量保存数据

转载请标明出处:一片枫叶的专栏 上一篇文章中我们讲解了Android中的几种常见网络协议:xml,json,protobuf等,以及各自的优缺点,一般而言主要我们的App涉及到了网络传输都会有这方...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)