Android XML PULL 数据解析
除了前面的 SAX 和 DOM 解析 XML 文件外, Android 系统其实内置了 PULL 解析器用来解析 XML 文件
PULL 和 SAX 有点类似,都是釆用事件驱动来完成 xml 的解析的
而 PULL
的编码较为简单,只需处理开始与结束事件,通常是使用 switch
语句根据事件的不同类型匹配不同的处理方式
PULL
有五种事件
START_DOCUMENT START_TAG TEXT END_TAG END_ DOCUMENT
PULL
解析过程中返回的是数宇,且我们需要自己获取产生的事件然后做相应的操作,而不像 SAX 那样由处理器触发一种事件的方法,执行我们的代码
PULL 解析 XML 数据的流程
-
获得一个
XMLPullParser
类的实例有两种方式
-
通过 XML 解析工厂获得实例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser();
-
直接获得实例
XmlPullParser parser = Xml.newPullParser();
-
-
为
parser
解析器提供 xml 数据和编码格式parser.setInput(xml,"UTF-8");
-
获得事件的类型
int eventType = parset.eventType();
-
使用
switch
语句对不同的事件类型进行分类处理事件类型 说明 START_DOCUMENT 开始读取文档时触发,可以完成一些初始化操作 START_TAG 读到某个元素的开始标签时触发
可以通过parser.getName()
获得表签名
可以通过parser.getAttributeValue(index)
取出属性的值TEXT 遇到文字节点时触发,可以通过 parser.nextText()
获得文件内容END_TAG 遇到元素的结束标签时触发 END_DOCUMENT 文档解析结束时触发 另外,可以通过
parser.next()
跳到下一个元素int eventType = parset.eventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: persons = new ArrayList<Person>(); break; case XmlPullParser.START_TAG: if ("person".equals(parser.getName())) { person = new Person(); // 取出属性值 int id = Integer.parseInt(parser.getAttributeValue(0)); person.setId(id); } else if ("name".equals(parser.getName())) { String name = parser.nextText();// 获取该节点的内容 person.setName(name); } else if ("age".equals(parser.getName())) { int age = Integer.parseInt(parser.nextText()); person.setAge(age); } break; case XmlPullParser.END_TAG: if ("person".equals(parser.getName())) { persons.add(person); person = null; } break; } eventType = parser.next(); }
范例
-
创建一个 空的 Android 项目
cn.twle.android.PullParser
-
在
app
上点右键,选择Folder - Assets Folder
创建assets
目录,并在assets
目录下新建文件languages.xml
,内容如下<?xml version="1.0" encoding="utf-8" ?> <languages> <language id="1"> <name>Java</name> <rank>1</rank> </language> <language id="2"> <name>C</name> <rank>2</rank> </language> <language id="3"> <name>C++</name> <rank>3</rank> </language> </languages>
-
修改
activity_main.xml
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="8dp" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="XML 内容 " /> <TextView android:id="@+id/ms_src" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" /> <Button android:text="解析" android:id="@+id/btn_parser" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解析后得到内容 " /> <TextView android:id="@+id/ms_dst" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" /> </LinearLayout>
-
创建一个 POJO 业务类
Language.java
package cn.twle.android.pullparser; public class Language { private int id; private String name; private String rank; public Language() { } public void setId(int id) { this.id = id; } public int getId() { return this.id; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setRank(String rank) { this.rank = rank; } public String getRank() { return this.rank; } }
-
修改
MainActivity.java
package cn.twle.android.pullparser; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; public class MainActivity extends AppCompatActivity{ private TextView ms_src, ms_dst; private Button btn_parser; private ArrayList<Language> languages; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ms_dst = findViewById(R.id.ms_dst); ms_src = findViewById(R.id.ms_src); btn_parser = findViewById(R.id.btn_parser); btn_parser.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获取文件资源建立输入流对象 try { InputStream is = getAssets().open("languages.xml"); languages = parser(is); if (languages.equals(null)) { ms_dst.setText("解析失败"); } StringBuilder sb2 = new StringBuilder(); for (Language p1 : languages) { sb2.append(p1.getId() + ". " + p1.getName() + "的排名是:" + p1.getRank() + "\n"); } ms_dst.setText(sb2.toString()); } catch (Exception e) { e.printStackTrace(); } } }); StringBuilder sb = new StringBuilder(); try { InputStream is = getResources().getAssets().open("languages.xml"); InputStreamReader isr = new InputStreamReader(is,"UTF-8"); BufferedReader br = new BufferedReader(isr); String str = ""; while((str = br.readLine()) != null){ sb.append(str); } } catch (IOException e) { e.printStackTrace(); } ms_src.setText(sb.toString()); } public static ArrayList<Language> parser(InputStream xml) throws Exception { //XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance(); ArrayList<Language> langs = null; Language language = null; // 创建一个xml解析的工厂 XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); // 获得xml解析类的引用 XmlPullParser parser = factory.newPullParser(); parser.setInput(xml, "UTF-8"); // 获得事件的类型 int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: langs = new ArrayList<Language>(); break; case XmlPullParser.START_TAG: if ("language".equals(parser.getName())) { language = new Language(); // 取出属性值 int id = Integer.parseInt(parser.getAttributeValue(0)); language.setId(id); } else if ("name".equals(parser.getName())) { String name = parser.nextText();// 获取该节点的内容 language.setName(name); } else if ("rank".equals(parser.getName())) { String rank = parser.nextText(); language.setRank(rank); } break; case XmlPullParser.END_TAG: if ("language".equals(parser.getName())) { langs.add(language); language = null; } break; } eventType = parser.next(); } return langs; } }