XML解析之——PULL解析

XML介绍:Extensible Markup Language  即:可扩展标记语言

一、概述

Android中的XML解析有三种方式:

1、DOM

2、SAX

3、PULL

二、详解

2.1 SAX

SAX(Simple API  for XML)使用流式处理的方式,它并不记录所读内容的相关信息。它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调方法来实现。缺点是不能倒退。

2.2 DOM

DOM(Document Object Model)是一种用于XML文档的对象模型,可用于直接访问XML文档的各个部分。它是一次性全部将内容加载到内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。缺点是加载大文档时效率低下。

2.3 PULL 内置于Android系统中,也是官方解析布局文件所使用的方式。

PULL  与 SAX有点类似,都提供了类似的事件,如开始元素和结束元素。

不同的是,SAX的事件是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用响应的方法。而PULL解析器并没有强制要求提供触发方法。以为它触发的事件不是一个方法,而是一个数字。它使用方便效率高。

三、比较

SAX 、DOM、PULL比较

内存占用:SAX 、PULL 比DOM好。

编程方式:SAX采用事件驱动,在响应事件触发的时候,会调用用户编号的方法,也即每解析一类XML,就要编写一个新的适合该类的XML处理类。DOM是W3C的规范。PULL 简介易用。

访问与修改:SAX采用流式解析,DOM随机访问。

访问方式:SAX、PULL解析方式是同步,DOM是逐字逐句。

四、PULL解析

PULL解析需要了解的几个解析类型:

XmlPullParser.START_DOCUMENT=0(开始解析文档),
XmlPullParser.EDN_DOCUMENT=1(结束解析文档),
XmlPullParser.START_TAG=2(开始解析标签),
XmlPullParser.END_TAG=3(结束解析标签);
XmlPullParser.TEXT=4(解析文本时用的);

4.1 PULL解析实例。

1、在Assets文件夹下创建一个Movies.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<movies>
    <movie>
        <name>《星际穿越》</name>
        <director>克里斯托弗诺兰</director>
        <country>美国</country>
    </movie>
    <movie>
        <name>《罗生门》</name>
        <director>黑泽明</director>
        <country>日本</country>
    </movie>
    <movie>
        <name>《老男孩》</name>
        <director>朴赞郁</director>
        <country>韩国</country>
    </movie>
    <movie>
        <name>《芳华》</name>
        <director>冯小刚</director>
        <country>中国</country>
    </movie>


</movies>

2、根据这个XML的元素创建一个Movie的实体类

package com.example.pc.xmlparsetest;

/**
 * Created by pc on 2018/6/1.
 */

public class Movie {

    private String name;
    private String director;
    private String country;

    public Movie() {
    }

    public Movie(String name, String director, String country) {
        this.name = name;
        this.director = director;
        this.country = country;
    }

    public String getName() {
        return name;
    }

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

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return "Movie{" +
                "name='" + name + '\'' +
                ", director='" + director + '\'' +
                ", country='" + country + '\'' +
                '}';
    }
}

3、因为解析文件比较耗时,所以创建一个ParseThread类继承自Thread。在run()方法中执行解析操作,解析完成后把返回的list集合通过handler.post()显示到Activiy的TextView中。

package com.example.pc.xmlparsetest;

import android.content.res.AssetManager;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by pc on 2018/6/1.
 */

public class ParseThread extends Thread {

    private Handler handler;
    private TextView showMovies;
    private InputStream is;
    final List<Movie> movies=new ArrayList<Movie>();


    public ParseThread(Handler handler,TextView showMovies,InputStream is){

        this.handler=handler;
        this.showMovies=showMovies;
        this.is=is;


    }


    @Override
    public void run() {


        try {
            // 通过XmlPullParserFactory.newInstance()获取PullParser的工厂实例。
            XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
            //通过PullParser的工厂实例创建XmlPullParser实例。
            XmlPullParser parser=factory.newPullParser();
            //给Parser设置输入流,和编码方式。
            parser.setInput(is,"UTF-8");
            //获取事件类型
           int eventType= parser.getEventType();
            Log.i("TAG","in run ");

            Movie m=null;
            //在到达END_DOCUMENT(文档结束)时停止解析。
           while(eventType!=XmlPullParser.END_DOCUMENT){
               //获取事件名称
               String data=parser.getName();
               //判断事件类型
               switch (eventType){
                   //如果是开始标签则开始判断事件名称并执行相应操作。
                   case XmlPullParser.START_TAG:
                       //事件名称是movie则创建一个Movie对象
                       if(data.equals("movie")){
                            m=new Movie();
                      //如果事件名称是name则将,name后接的value值添加到m中
                       }if(data.equals("name")){
                       Log.i("TAG","data="+data);
                           m.setName(parser.nextText());
                   }if(data.equals("director")){
                           m.setDirector(parser.nextText());
                   }if(data.equals("country")){
                       m.setCountry(parser.nextText());
                   }
                   break ;
                   //如果是结束标签是“movie”则将movie添加到List集合中。
                   case XmlPullParser.END_TAG:
                       if(data.equals("movie")){
                            movies.add(m);
                       }

                       break;
               }
               //获取下一个事件类型
               eventType=parser.next();
           }
          is.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        handler.post(new Runnable() {
            @Override
            public void run() {
                //显示结果
                showMovies.setText(movies.toString());
            }
        });

        super.run();
    }
}

4、结果显示







参考:https://www.cnblogs.com/neillee/p/7281687.html


猜你喜欢

转载自blog.csdn.net/mahuicool/article/details/80556957