一、简述Pull解析XML特点
Pull解析XML和Sax解析XML是差不多的,区别就是Sax扫描解析文档是自动进行的,而Pull扫描解析文档需要我们手动调用next()
方法进行。每扫描到相应的内容会报相应的事件,我们需要自己写代码逻辑根据相应的事件进行处理。
其中,Pull解析XML文档有5种事件:
- START DOCUMENT:文档开始事件,文档还没有扫描任何的内容;
- START_TAG:标签开始事件,解析器在开始标签;
- TEXT:文本事件,解析器在节点内容处;
- END_TAG:标签开始事件,解析器在结束标签;
- END_DOCUMENT:文档结束事件,解析器解析文档结束。
二、举个例子
解析如下persons.xml
<?xml version="1.0" encoding="utf-8" ?>
<persons>
<person id="p1">
<name>小明</name>
<age>18</age>
</person>
<person id="p2">
<name>小华</name>
<age>23</age>
</person>
</persons>
pull解析xml逻辑类
import android.text.TextUtils
import com.mapc.demo.pojo.Person
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
import java.io.InputStream
class XmlPullParser{
/**
* 放在里面,类似Java静态成员、静态方法,可以直接:类名.xx
*/
companion object {
private lateinit var personList:ArrayList<Person>
private var currentTag:String?=null//解析的当前标签
private var nodeName:String?=null//记录开始解析的节点标签
private var person:Person?=null//一个节点的封装对象
fun parseXmlForPersonList(inputStream:InputStream,nodeName:String):ArrayList<Person>?{
this.nodeName = nodeName
//创建解析器工厂
var factory = XmlPullParserFactory.newInstance()
//创建解析器
var parser = factory.newPullParser()
//解析器设置解析文档流
parser.setInput(inputStream,"utf-8")
//获取第一个事件类型
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT){
when(eventType){
XmlPullParser.START_DOCUMENT ->{
personList = ArrayList<Person>()
}
XmlPullParser.START_TAG ->{
if (!TextUtils.isEmpty(parser.name)){
println("--------------标签${parser.name}--------------")
this.currentTag = parser.name
if (this.currentTag == this.nodeName) {
person = Person(null, null, null)
if (parser.attributeCount>0){
person?.id = parser.getAttributeValue(0)
}
}else{
when(this.currentTag){
"name" -> this.person?.name = parser.nextText()
"age" -> this.person?.age = parser.nextText()
}
}
}
}
XmlPullParser.TEXT ->{
//等价于上面
// if(!TextUtils.isEmpty(this.currentTag)){
// when(this.currentTag){
// "name" -> this.person?.name = parser.text
// "age" -> this.person?.age = parser.text
// }
// }
}
XmlPullParser.END_TAG ->{
if (!TextUtils.isEmpty(parser.name) && parser.name==this.nodeName){
this.personList.add(this.person as Person)
this.person=null
this.currentTag=null
}
}
XmlPullParser.END_DOCUMENT ->{}
}
eventType = parser.next()
}
return personList
}
}
}
调用测试
var inputStream = this.assets.open("persons.xml")
var list = XmlPullParser.parseXmlForPersonList(inputStream,"person")
[完整demo]
参考资料:
2、解析XML数据