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.EDN_DOCUMENT=1(结束解析文档),
XmlPullParser.START_TAG=2(开始解析标签),
XmlPullParser.END_TAG=3(结束解析标签);
XmlPullParser.TEXT=4(解析文本时用的);
4.1 PULL解析实例。
<?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