PULL方式解析XML是在Android中推荐使用的一种解析XML的方式。
事件类型
- START_DOCUMENT:文档开始,解析器还未读取到任何输入的时候
- START_TAG:解析到开始标签
- TEXT:解析到文本节点
- END_TAG:解析到结束标签
- END_DOCUMENT:文档结束
常用方法
// 获取指定索引属性的属性值,索引从0开始
public abstract String getAttributeValue (int index);
public abstract String getAttributeValue(String namespace, String name);
// 返回当前事件类型
public abstract int getEventType ();
// 返回当前事件类型的内容字符串形式
public abstract String getText ();
// 获取下一个解析事件类型
public abstract int next ();
// 当前是开始标签,如果下一个元素为文本,则返回该文本字符串,
// 如果下一个元素是结束标签,则返回空字符串,其它情况将抛出异常
public abstract String nextText ();
// 设置即将被解析的输入流
public abstract void setInput (InputStream inputStream, String inputEncoding);
Android示例
private void parseLayout(int layout) {
Resources resources = getResources();
XmlPullParser parser = resources.getLayout(layout);
try {
int type = parser.getEventType();
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_DOCUMENT:
Log.i("steven", "START_DOCUMENT - " + parser.getName());
break;
case XmlPullParser.START_TAG:
Log.i("steven", "START_TAG -- " + parser.getName());
int attrCount = parser.getAttributeCount();
String separator = " , ";
for (int i = 0; i < attrCount; i++) {
StringBuffer sb = new StringBuffer();
sb.append("name = ");
sb.append(parser.getAttributeName(i));
sb.append(separator);
sb.append("value = ");
sb.append(parser.getAttributeValue(i));
sb.append(separator);
sb.append("type = ");
sb.append(parser.getAttributeType(i));
Log.i("steven", sb.toString());
}
break;
case XmlPullParser.END_TAG:
Log.i("steven", "END_TAG --" + parser.getName());
break;
}
type = parser.next();
}
Log.i("steven", "END_DOCUMENT - " + parser.getName());
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
XML布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/item_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp" />
</LinearLayout>
输出日志
I/steven (30085): START_DOCUMENT - null
I/steven (30085): START_DOCUMENT - null
I/steven (30085): START_TAG -- LinearLayout
I/steven (30085): name = orientation , value = 0 , type = CDATA
I/steven (30085): name = layout_width , value = -2 , type = CDATA
I/steven (30085): name = layout_height , value = -2 , type = CDATA
I/steven (30085): START_TAG -- ImageView
I/steven (30085): name = id , value = @2131427425 , type = CDATA
I/steven (30085): name = layout_width , value = -2 , type = CDATA
I/steven (30085): name = layout_height , value = -2 , type = CDATA
I/steven (30085): END_TAG --ImageView
I/steven (30085): START_TAG -- TextView
I/steven (30085): name = id , value = @2131427426 , type = CDATA
I/steven (30085): name = layout_width , value = -2 , type = CDATA
I/steven (30085): name = layout_height , value = -2 , type = CDATA
I/steven (30085): name = layout_marginLeft , value = 10.0dip , type = CDATA
I/steven (30085): END_TAG --TextView
I/steven (30085): END_TAG --LinearLayout
I/steven (30085): END_DOCUMENT - null
示例
public static List<Employee> readXml(InputStream in, String encode) {
List<Employee> emps = null;
Employee emp = null;
try {
// 创建解析器工厂对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 从工厂中获取解析器对象
XmlPullParser parser = factory.newPullParser();
// 设置解析器输入
parser.setInput(in, encode);
/* 解析 */
// 获取解析到的事件类型
int eventType = parser.getEventType();
// 未解析到文档结尾,则循环解析
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT: // 文档开始事件
// 创建List集合对象
emps = new ArrayList<Employee>();
break;
case XmlPullParser.START_TAG: // 标签开始事件
String nodeName = parser.getName().trim(); // 节点名称
if ("employee".equals(nodeName)) { // employee节点
emp = new Employee(); // 创建员工对象
// 该节点有id属性,则获取id属性
int id = Integer.parseInt(parser.getAttributeValue(
null, "id"));
emp.setId(id);
} else if ("name".equals(nodeName)) { // name节点
String name = parser.nextText().trim();
emp.setName(name);
} else if ("age".equals(nodeName)) { // age节点
int age = Integer.parseInt(parser.nextText().trim());
emp.setAge(age);
} else if ("address".equals(nodeName)) { // address节点
String address = parser.nextText();
emp.setAddress(address);
}
break;
case XmlPullParser.END_TAG:
if ("employee".equals(parser.getName().trim())) {
emps.add(emp);
emp = null;
}
break;
}
eventType = parser.next(); // 切换到下一个解析事件
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return emps;
}
<employees>
<employee id="1">
<name>小明</name>
<age>29</age>
<address>四川成都</address>
</employee>
<employee id="2">
<name>老骆</name>
<age>35</age>
<address>四川成都</address>
</employee>
</employees>