在android开发中,经常用到去解析xml文件。我们今天来学习一下XML文件的解析,在java中我们应该知道两种解析方式:DOM和SAX解析方式,我这里就不讲解DOM和SAX的解析方式了,有兴趣的同学可以向我要示例或者自己上网查查,这里重点讲解一下Android中常用并且官方推荐的方式:
PULL解析方式
PULL解析方式采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。
步骤:
①拿到加载资源文件XML的解析器
②通过解析器获得事件类型
③根据事件类型判断并获取相应的值
那来做下吧,
准备了一个简单的xml文件:
movie.xml
<?xml version="1.0" encoding="UTF-8"?>
<Movies>
<Movie id="1">
<name>愤怒的小鸟</name>
<type>animation</type>
<language>English</language>
</Movie>
<Movie id="2">
<name>叶问</name>
<type>action</type>
<language>chinese</language>
</Movie>
</Movies>
在res/目录下新建一个文件夹xml,将此xml文件放进去。
可以看到最外层的节点 Movies 中包含两个 Movie ,而每个 Movie 中又包含三个属性:name 、type 、language
所以我们可以新建一个Movie 类来保存解析出来的每个 Movie , Movie中应该有四个属性 id 、name 、type 、language
Movie.java
public class Movie {
private String id; //id
private String name; //电影名
private String type; //电影类型
private String language;//语言
public Movie() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
@Override
public String toString() {
return "Movie [id=" + id + ", name=" + name + ", type=" + type
+ ", language=" + language + "]";
}
}
布局文件:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.Pull_XML.MainActivity" >
<TextView
android:id="@+id/show"
android:textSize="30sp"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="pull"
android:text="pull解析" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
private TextView show;
private Movie movie;
private List<Movie> movieList; //存放电影的集合
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show = (TextView) findViewById(R.id.show);
}
/*
* 这是一个按钮的点击事件
*
* 在这里用pull方式来解析xml文件
*/
public void pull(View view) {
//从xml资源文件夹加载movie.xml文件
XmlResourceParser XmlParser = getResources().getXml(R.xml.movie);
// 拿到第一个事件类型,事件类型为END_DOCUMENT,START_DOCUMENT,START_TAG,END_TAG等
try {
int type = XmlParser.getEventType();
while (type != XmlResourceParser.END_DOCUMENT) { //结束节点(即</Movies>),只要不是结束节点就遍历
switch (type) {
case XmlResourceParser.START_DOCUMENT: //开始节点(即<Movies> )
System.out.println("开始解析");
movieList = new ArrayList<Movie>();
break;
case XmlResourceParser.START_TAG:
if ("Movie".equals(XmlParser.getName())) { //开始元素(<Movie>)
//getAttributeValue获得Movie节点的属性
movie = new Movie();
movie.setId(XmlParser.getAttributeValue(null, "id"));
}
if ("name".equals(XmlParser.getName())) { //开始子元素(<name>)
/// 通过nextText()就可以获得子节点的文本的值
movie.setName(XmlParser.nextText());
}
if ("type".equals(XmlParser.getName())) { //开始子元素(<type>)
/// 通过nextText()就可以获得子节点的文本的值
movie.setType(XmlParser.nextText());
}
if ("language".equals(XmlParser.getName())) { //开始子元素(<language>)
/// 通过nextText()就可以获得子节点的文本的值
movie.setLanguage(XmlParser.nextText());
}
break;
case XmlResourceParser.END_TAG:
if ("Movie".equals(XmlParser.getName())) { //结束元素(</Movie>)
movieList.add(movie);
movie = null;
}
break;
default:
break;
}
//获取下一个解析事件((即开始文档,结束文档,开始标签,结束标签))
type = XmlParser.next();
}
} catch (IOException e) {
e.printStackTrace();
}
catch (XmlPullParserException e) {
e.printStackTrace();
}
//解析结束,将结果显示在TextView上
show.setText(movieList.toString());
}
}
大家看看注释,应该很清楚。当然,除以上三种外还有很多解析xml的方法,比如DOM4J、JDOM等等。但其基本的解析方式包含两种,一种是事件驱动的(代表SAX),另一种方式是基于文档结构(代表DOM)。其他的只不过语法不一样而已。
结果: