一、XmlPullParser 概述
-
XmlPullParser 是 Android 平台上用于解析 XML 数据的一个接口,它提供了更高效的方式来读取 XML 文档
-
XmlPullParser 不会一次性将整个 XML 文档加载到内存中,而是采用流式读取的方式,即边读取边解析,这样可以大大减少对内存的使用,特别适合处理大型 XML 文件
二、XmlPullParser 基本使用
1、使用步骤
- 获取解析器实例
XmlPullParser xmlPullParser = Xml.newPullParser();
- 设置输入源并指定字符编码,这里设置为 null 表示使用默认的字符编码,通常是 UTF-8
InputStream inputStream = getResources().openRawResource(R.raw.users);
xmlPullParser.setInput(inputStream, null);
- 获取事件类型
int eventType = xmlPullParser.getEventType();
- 每当解析器遇到 XML 文档中的一个重要部分时,它都会触发一个事件,我们通过检查事件类型来决定如何处理数据,有如下事件类型
int START_DOCUMENT = 0;
int END_DOCUMENT = 1;
int START_TAG = 2;
int END_TAG = 3;
int TEXT = 4;
事件 | 说明 |
---|---|
START_DOCUMENT | 表示文档开始 |
END_DOCUMENT | 表示文档结束 |
START_TAG | 表示开始标签 |
END_TAG | 表示结束标签 |
TEXT | 表示标签之间的文本内容 |
- 移动到 XML 文档中的下一个元素,并返回新的事件类型
int next = xmlPullParser.next();
- 获取标签的名称,该方法只有在
START_TAG
或END_TAG
事件上调用时,才会返回标签的名称,否则返回 null
String name = xmlPullParser.getName();
- 获取标签之间的文本内容
String text = xmlPullParser.getText();
2、演示
- user.xml,准备好 XML 文件,该文件放置在
res/raw
目录下,这样,在 Activity 中可通过getResources().openRawResource()
获取到该目录下的资源
<users>
<user>
<name>jack</name>
<age>21</age>
</user>
<user>
<name>tom</name>
<age>22</age>
</user>
</users>
- 测试代码
InputStream inputStream = getResources().openRawResource(R.raw.users);
XmlPullParser xmlPullParser = Xml.newPullParser();
try {
xmlPullParser.setInput(inputStream, null);
Log.i(TAG, "------------------------------ 文档开始");
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 users 开始标签");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 users 标签之间的文本内容");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 user 开始标签");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 user 标签之间的文本内容");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 name 开始标签");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 name 标签之间的文本内容");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
Log.i(TAG, "------------------------------ 到 name 结束标签");
xmlPullParser.next();
Log.i(TAG, "--------------- " + xmlPullParser.getEventType());
Log.i(TAG, "--------------- " + xmlPullParser.getName());
Log.i(TAG, "--------------- " + xmlPullParser.getText());
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
- 输出结果
I/GetXmlActivity: ------------------------------ 文档开始
I/GetXmlActivity: --------------- 0
I/GetXmlActivity: --------------- null
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ------------------------------ 到 users 开始标签
I/GetXmlActivity: --------------- 2
I/GetXmlActivity: --------------- users
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ------------------------------ 到 users 标签之间的文本内容
I/GetXmlActivity: --------------- 4
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ---------------
I/GetXmlActivity: ------------------------------ 到 user 开始标签
I/GetXmlActivity: --------------- 2
I/GetXmlActivity: --------------- user
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ------------------------------ 到 user 标签之间的文本内容
I/GetXmlActivity: --------------- 4
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ---------------
I/GetXmlActivity: ------------------------------ 到 name 开始标签
I/GetXmlActivity: --------------- 2
I/GetXmlActivity: --------------- name
I/GetXmlActivity: --------------- null
I/GetXmlActivity: ------------------------------ 到 name 标签之间的文本内容
I/GetXmlActivity: --------------- 4
I/GetXmlActivity: --------------- null
I/GetXmlActivity: --------------- jack
I/GetXmlActivity: ------------------------------ 到 name 结束标签
I/GetXmlActivity: --------------- 3
I/GetXmlActivity: --------------- name
I/GetXmlActivity: --------------- null
3、演示优化
(1)优化思路
-
对于
<name>jack</name>
,我们只关注 name 标签之间的文本内容 -
即当
xmlPullParser.getEventType() == XmlPullParser.START_TAG
以及xmlPullParser.getName().equals("name")
时,我们已经到 name 开始标签 -
这个时候再走一步,即可获取到 name 标签之间的文本内容,即
xmlPullParser.next()
之后xmlPullParser.getText()
(2)具体实现
- 测试代码,这次我们只关注标签之间的文本
InputStream inputStream = getResources().openRawResource(R.raw.users);
XmlPullParser xmlPullParser = Xml.newPullParser();
try {
xmlPullParser.setInput(inputStream, null);
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = xmlPullParser.getName();
if (name.equals("name")) {
xmlPullParser.next();
String text = xmlPullParser.getText();
Log.i(TAG, "--------------- name: " + text);
} else if (name.equals("age")) {
xmlPullParser.next();
String text = xmlPullParser.getText();
Log.i(TAG, "--------------- age: " + text);
}
}
eventType = xmlPullParser.next();
}
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
- 输出结果
I/GetXmlActivity: --------------- name: jack
I/GetXmlActivity: --------------- age: 21
I/GetXmlActivity: --------------- name: tom
I/GetXmlActivity: --------------- age: 22
三、XmlPullParser 实例实操
1、案例引入
- 将如下的 XML 文件,希望将它解析成 2 个 User 对象,并放入
List<User> users
集合中
<users>
<user>
<name>jack</name>
<age>21</age>
</user>
<user>
<name>tom</name>
<age>22</age>
</user>
</users>
2、案例思路
-
当
xmlPullParser.getEventType() == XmlPullParser.START_TAG
以及xmlPullParser.getName().equals("user")
时,我们已经到 user 开始标签 -
这个时候我们创建 User 对象
-
当
xmlPullParser.getEventType() == XmlPullParser.START_TAG
以及xmlPullParser.getName().equals("name")
时,我们已经到 name 开始标签 -
这个时候我们再走一步,即可获取到 name 标签之间的文本内容并传递给 User 对象
-
当
xmlPullParser.getEventType() == XmlPullParser.START_TAG
以及xmlPullParser.getName().equals("age")
时,我们已经到 name 开始标签 -
这个时候我们再走一步,即可获取到 age 标签之间的文本内容并传递给 User 对象
-
当
xmlPullParser.getEventType() == XmlPullParser.END_TAG
以及xmlPullParser.getName().equals("user")
时,我们已经到 user 结束标签 -
这个时候我们把 User 对象放入 users 集合中
3、具体实现
(1)Entity
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(2)Test Code
List<User> users = new ArrayList<>();
User user = null;
InputStream inputStream = getResources().openRawResource(R.raw.users);
XmlPullParser xmlPullParser = Xml.newPullParser();
try {
xmlPullParser.setInput(inputStream, null);
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = xmlPullParser.getName();
if (name.equals("user")) {
user = new User();
} else if (name.equals("name")) {
xmlPullParser.next();
String text = xmlPullParser.getText();
user.setName(text);
} else if (name.equals("age")) {
xmlPullParser.next();
String text = xmlPullParser.getText();
try {
user.setAge(Integer.parseInt(text));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
} else if (eventType == XmlPullParser.END_TAG) {
String name = xmlPullParser.getName();
if (name.equals("user")) {
users.add(user);
}
}
eventType = xmlPullParser.next();
}
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
for (User u : users) {
Log.i(TAG, "---------- " + u);
}
- 输出结果
I/GetXmlActivity: ---------- User{name='jack', age=21}
I/GetXmlActivity: ---------- User{name='tom', age=22}