【XML解析】Pull解析XML

一、简述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]


参考资料:

1、XML Pull Parsing

2、解析XML数据

猜你喜欢

转载自blog.csdn.net/u012995888/article/details/80213480