转自https://www.cnblogs.com/GeekSeer/p/5981125.html,感谢作者的无私分享。
Pull解析与Sax一样.都属于事件驱动的解析方式.。相比Sax解析过程更加灵活.
sax一旦开始解析就是从头读到尾.不解析完整个文档不会停。
pull解析较为灵活.是以事件为单位.手动向下继续. 如果获得到我们要找的内容. 可以停止继续解析.
对象的种类
Document 整个xml文档对象
Element 文档中的标签对象
Atritube 标签中的属性对象
Text 标签体的内容的对象
Common 注释对象
常用事件
START_DOCUMENT 文档开始
END_DOCUMENT 文档结束
START_TAG 元素开始
END_TAG 元素结束
常用方法
1.xml解析获得标签属性值:
String number = parser.getAttributeValue(0); //通过索引获取 这边只有一个属性number
String number =parser.getAttributeValue(null,"cityname"); //null:固定值;cityname:属性的名字
2.获得开始标签之后的标签体内容
if("name".equals(parser.getName())){ //解析到了name开始标签就获取值
String name = parser.nextText(); //xml解析获得文本属性parser.nextText(); 注意:这边if条件中获取的是name标签开始的位置 因此用nextText()方法获取标签体内容
stu.setName(name);
}
public class PullTool {
//写一个解析XML文件的方法
/**
* 返回值:List<Student>
* 参数:InputStream is
* 注意 工具类中的方法写成静态
* @throws XmlPullParserException
*/
public static List<Student> parserXml(InputStream is) throws Exception{
//A.初始化集合以及Student对象
List<Student> list = null;
Student stu = null;
//B.创建生产XML的pull解析器的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//C.使用工厂获取pull解析器
XmlPullParser parser = factory.newPullParser();
//D.使用解析器读取当前的xml流
parser.setInput(is, "UTF-8");
//传入InputStream对象 并且设置解码规则需和XML文档中设置的一致
//E.获取当前事件的状态
int type = parser.getEventType();
/**
* 我们知道pull解析是以事件为单位解析
的因此我们要获取一开始的解析标记type,之后通过type判断循环来读取文档
* 注意:当解析器开始读取is的时候已经开
始了,指针type在xml的第一行开始。pull解析是指针从第一行
开始读取到最后一行以事件为单位读取的解析方式
*/
//F.通过while循环判断是否读取到了文档结束
while(type != parser.END_DOCUMENT){
switch (type) {
case XmlPullParser.START_TAG:
//判断当前遇到的元素名称是否为students
if("students".equals(parser.getName())){
list = new ArrayList<Student>();
}else if("student".equals(parser.getName())){
//初始化Student对象
stu = new Student();
//读取number属性
String number = parser.getAttributeValue(null,"number");
//String number = parser.getAttributeValue(0);
//也可以通过索引获取 这边只有一个属性number
//xml解析获得标签属性值:parser.getAttributeValue(null,"cityname")
//null:固定值;cityname:属性的名字
stu.setNumber(number); //将数据封装到学生类中
}else if("name".equals(parser.getName())){
String name = parser.nextText();
//xml解析获得文本属性
//parser.nextText();
注意:这边if条件中获取的是name标签开始的位置
//因此用nextText()方法获取标签体内容
stu.setName(name);
}else if("sex".equals(parser.getName())){
String sex = parser.nextText();
stu.setSex(sex);
}else if("age".equals(parser.getName())){
int age = Integer.parseInt(parser.nextText());
stu.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if("student".equals(parser.getName())){
list.add(stu);
stu = null;
}
break;
default:
break;
}
//让解析器向下解析一行,并返回改行的事件常量
// 这样配合while(type != parser.END_DOCUMENT)读取完整个文档
type = parser.next();
}
return list;
}
public static void main(String[] args) throws Exception {
FileInputStream is = new FileInputStream("src/stu.xml");
List<Student> list = PullTool.parserXml(is);
System.out.println(list);
is.close();
}
}
//使用Xml pull 解析器去解析 xml 文件的内容
XmlPullParser xmlPullParser = Xml.newPullParser();
try {
//解析的源是什么?- - - result.xml
InputStream in = getAssets().open("result.xml");
xmlPullParser.setInput(in,"utf-8");
//获得一个事件类型
int eventType = xmlPullParser.getEventType();
//准备Product类的一个实例,去封装数据
Product p =null;
while (eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG){
//判断是否是元素的开始,只要是某个元素的开始位置,那么就会进入这里
//获得当前解析到的元素的名称
if("product".equals(xmlPullParser.getName())){
p = new Product();
String type = xmlPullParser.getAttributeValue(0);
p.setType(type);
}else if("phonenum".equals(xmlPullParser.getName())){
String number = xmlPullParser.nextText();
p.setNumber(number);
}else if("location".equals(xmlPullParser.getName())){
String location = xmlPullParser.nextText();
p.setLocation(location);
}else if("phoneJx".equals(xmlPullParser.getName())){
String phoneJx = xmlPullParser.nextText();
p.setPhoneJx(phoneJx);
System.out.println(p);
}
}
eventType=xmlPullParser.next();
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}