使用PULL方式解析XML:

Pull是STAX的一个实现

StAX是The Streaming API for XML的缩写,一种利用拉模式解析(pull-parsing)XML文档的API

StAX通过提供一种基于事件迭代器(Iterator)的API让程序员去控制xml文档解析过程。

为什么说StAX方式的效率优于SAX呢?

因为SAX 是推模式的,所有的操作在解析器自动控制下进行,所有事件都会处理,不管需不需要解析整个文档,解析器都会自动启动解析任务,然后按顺序向下解析,直到解析完成才终止。而StAX 是拉模式的,可以由用户根据需要控制需要处理事件类型及何时终止解析任务,用户调用一次next(),解析器就进行一次向下解析,完全在用户的控制下进行解析操作,在需要的解析工作已经完成时,可以随时终止解析。

简单说来,推模式,就是你把如何操作通通告诉解析器,之后,解析器自动去完成所有解析任务,你不能做任何干涉了。

而拉模式就像抽纸,随用随拉,需要时就拉一下,不需要时,它不会自动推出来。你可以一直拉把一盒抽纸拉完,也可以按自己需要只拉几张。

可以从网上下载PULL解析的第三方jar包,来使用PULL解析XML

www.xmlpull.org上有3种PULL的实现可以下载:

由描述信息可以看出,XPP3这种实现主要致力于性能和易于使用,而且,android内置的PULL解析器似乎也是XPP3,所以可以下载这种实现,来实现XML的PULL解析。

选择合适的XPP3下载:

如,我下载了:

下载完成后,解压缩,然后找到文件名类似于xpp3-1.1.4c.jar的jar包,这里面就有我们需要的API。

doc目录中的api目录中存放着API帮助手册,可以参考该手册,学习使用XPP3 PULL解析器。

如同DOM和SAX解析XML一样,PULL解析XML也要用到解析器工厂类XmlPullParserFactory,解析器类XmlPullParser,XPP3中还提供了XmlSerializer类用于将内存对象实现序列化到xml文档。

工厂类也是通过静态方法newInstance()获得工厂类对象。

newPullParser()和newSerializer()方法分别用于获取XmlPullParser对象和XmlSerializer对象。

以上就是工厂类的常用的三个方法。

XmlPulParser通过setInput()方法,设置要解析的XML文档。

通过调用next方法,一步步向下解析

通过调用getEventType()方法,来确认当前解析XML所触发的事件类型。

事件类型通过XmlPullParser中定义的几个常量来标识:

START_DOCUMENT:开始解析触发

START_DOCUMENT:碰到节点时触发

TEXT:读取字符文本时触发

END_TAG:碰到结束节点时触发

END_DOCUMENT:解析完成时触发

当触发事件类型是START_TAG或者END_TAG时,可以通过getName()方法获取当前节点名称。

当事件类型是START_TAG时,可以通过nextText()获取该节点的文本子节点内容,若事件类型为END_TAG则会返回一个空字符串。

当事件类型是START_TAG时,通过getAttributeCount()方法,可以获取该节点的属性个数

通过getAttributeName(int index)方法,可以获取指定index的属性的名称

通过getAttributeValue(int index)方法,可以获取指定index属性的值。

以上,是XmlPullParser类中的几个常用方法。

XmlSerializer实现将内存中的数据序列化到XML文档中,也有几个常用的方法:

setOutput()方法,指定要将数据序列化到哪个XML文件中

startDocument()方法,指定XML文档的开始<?xml声明信息

如:startDocument(“utf-8”, true);将在XML文档中输出如下信息:

<?xml encoding="UTF-8" standalone="yes"?>

startTag()开始一个节点,namespace没有,一般设置为null或者空字符串

text()设置文本内容

endTage()结束一个节点。

attribute()设置节点的属性。

了解了这几个类的常用方法后,就可以实现PULL模式的XML解析和序列化了。但是,现在有个问题:DOM可以实现增删改查操作,PULL模式可以吗?

由于在DOM模式下,整个文档对象都在内存中,所以可以实现修改回写。但是PULL模式以及SAX模式下,都是边解析边释放内存的,不能直接实现增删改查操作。但是,可以模仿DOM模式,把解析的部分保存在内存中,如把解析的对象都保存到一个List中。然后所有的增删改查操作,都针对List对象进行,所有操作执行完成之后,再把内存中最终版本的List序列化到Xml文档中,就间接实现了PULL模式下的增删改查操作。

具体操作可以参考下面代码:

待解析的students.xml:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>

 <students>

     <student id="000">

         <name>zhangsan22</name>

         <gender>female</gender>

         <age>26</age>

     </student>

     <student id="002">

         <name>lisi</name>

         <gender>male</gender>

         <age>24</age>

     </student>

     <student id="003">

         <name>xiaoqiao</name>

         <gender>female</gender>

         <age>18</age>

     </student>

     <student id="004">

         <name>diaochan</name>

         <gender>female</gender>

         <age>23</age>

     </student>

 </students>

对应的实体类:Student.java:

 package cn.csc.bean;

 public class Student {

          private String id = null;

          private String name = null;

          private String gender = null;

          private int age = 0;

          public String getId() {

                    return id;

          }

          public void setId(String id) {

                    this.id = id;

          }

          public String getName() {

                    return name;

          }

          public void setName(String name) {

                    this.name = name;

          }

          public String getGender() {

                    return gender;

          }

          public void setGender(String gender) {

                    this.gender = gender;

          }

          public int getAge() {

                    return age;

          }

          public void setAge(int age) {

                    this.age = age;

          }

          public Student(String id, String name, String gender, int age) {

                    super();

                    this.id = id;

                    this.name = name;

                    this.gender = gender;

                    this.age = age;

          }

          public Student() {

                    super();

          }

          public String toString() {

                    return "[id:"+id+",name:"+name+",gender:"+gender+",age"+age+"]";

          }

 }

StudentPullUtils类,实现两个方法,一个用于将xml文件中的student解析到List<Student>中,一个用于将List<Student>中的数据序列化到指定的xml文件中:

 public class StudentPullUtils {

          public static List<Student> parseXml(String filename) throws Exception{

                    List<Student> list = new ArrayList<Student>();

                    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                    XmlPullParser parser = factory.newPullParser();

                    parser.setInput(new FileInputStream(filename), "utf-8");

                    int eventType;

                    Student s = null;

                    while((eventType = parser.getEventType())!= XmlPullParser.END_DOCUMENT){

                             if(eventType == XmlPullParser.START_TAG && parser.getName().equals("student")){

                                      s = new Student();

                                      s.setId(parser.getAttributeValue(0));

                             }

                             if(eventType == XmlPullParser.START_TAG && parser.getName().equals("name")){

                                      s.setName(parser.nextText());

                             }

                             if(eventType == XmlPullParser.START_TAG && parser.getName().equals("age")){

                                      s.setAge(Integer.parseInt(parser.nextText()));

                             }

                             if(eventType == XmlPullParser.START_TAG && parser.getName().equals("gender")){

                                      s.setGender(parser.nextText());

                             }

                             if(eventType == XmlPullParser.END_TAG && parser.getName().equals("student")){

                                      list.add(s);

                             }

                             parser.next();

                    }

                    return list;

          }

          public static boolean serializeList(List<Student> list, String filename) throws Exception{

                    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                    XmlSerializer serializer = factory.newSerializer();

                    serializer.setOutput(new FileOutputStream(filename), "utf-8");

                    serializer.startDocument("utf-8", true);

                    serializer.startTag(null, "students");

                    for(Student s : list){

                             serializer.startTag(null, "student");

                             serializer.attribute(null, "id", s.getId());

                             serializer.startTag(null, "name");

                             serializer.text(s.getName());

                             serializer.endTag(null, "name");

                             serializer.startTag(null, "gender");

                             serializer.text(s.getGender());

                             serializer.endTag(null, "gender");

                             serializer.startTag(null, "age");

                             serializer.text(s.getAge()+"");

                             serializer.endTag(null, "age");

                             serializer.endTag(null, "student");

                    }

                    serializer.endTag(null, "students");

                    serializer.endDocument();

                    return true;

          }

 }

调用测试:实现将数据从students.xml中读取到Lis<Student>中,所有学生的年龄加1,然后序列化到students_bak.xml中:

 List<Student> list = StudentPullUtils.parseXml("students.xml");

 for(Student s: list){

          s.setAge(s.getAge()+1);

 }

 StudentPullUtils.serializeList(list, "students_bak.xml");

java拾遗3----XML解析(三) StAX PULL解析的更多相关文章

  1. [Java拾遗一] XML的书写规范与解析.

    前言今天天气大好, 起了个大早开始总结一些常用的基础知识. XML一直来说都很陌生, 使用大多是用于配置文件, 之前并没有细究过其中的约束规范, 今天刚好没事来学习并总结下. 1,XML基础介绍 XM ...

  2. Android初级教程:Android中解析方式之pull解析

    在安卓中有很多种解析方式.按照大方向有xml解析和json解析.而,细致的分,xml和json解析各有自己的很多解析方式.今天这一篇主要介绍xml解析中的pull解析.对于xml的解析方式,我之前在j ...

  3. Android(java)学习笔记187:Android中操作XML数据(使用Pull解析器)

    1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...

  4. Android(java)学习笔记130:Android中操作XML数据(使用Pull解析器)

    1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...

  5. Android笔记(四十七) Android中的数据存储——XML(三)SAX解析

    SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备. SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SA ...

  6. Android笔记(四十六) Android中的数据存储——XML(二)PULL解析

    PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText()从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDo ...

  7. 使用XML序列化器生成XML文件和利用pull解析XML文件

    首先,指定XML格式,我指定的XML格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <message&g ...

  8. EMV/PBOC解析(三) TLV格式解析(C#)

    1.什么是TLV格式? TLV即Tag-Length-Value,常在IC卡与POS终端设备中通过这样的一个应用通信协议进行数据交换. 金融系统中的TLV是BER-TLV编码的一个特例编码规范,而BE ...

  9. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

随机推荐

  1. crossapp里的位置设置

    crossapp里有Frame.Center,这两种都是可以用来确定一个view的位置和大小. 不同点:Frame定位是以View的左上角为参照点,Center是以View的中心点为参照点 注意cro ...

  2. 2017.7.25 jqGrid在编辑态无法获取数据,得到的是html代码

    页面如下: 勾选555之后,点击下方的删除按钮,调用如下代码: 最终调用的是jqGrid的getRowData()方法: 但是运行时发现,无法获取key的值,也就无法正确删除了.获取到的是html代码 ...

  3. 2017.4.26 慕课网--Java 高并发秒杀API配置文件(持续更新)

    新建项目,new maven project. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  4. Node.js 网页爬虫再进阶,cheerio助力

    任务还是读取博文标题. 读取app2.js // 内置http模块,提供了http服务器和客户端功能 var http=require("http"); // cheerio模块, ...

  5. python sqlite3 MySQLdb

    SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成. Python就 ...

  6. 【转载】Loadrunner实现Android / IOS 手机APP压力测试

    随着手机APP用户量的增大,大的手机APP一般都需要进行压力测试,这几天用了loadrunner 12进行了手机APP的压力测试,整理了下,大家可以参考参考怎样给Andorid / IOS手机APP进 ...

  7. 微博,and java 多线程编程 入门到精通 将cpu 的那个 张振华

    http://down.51cto.com/data/2263476  java 多线程编程 入门到精通  将cpu 的那个 张振华 多个用户可以同时用一个 vhost,但是vhost之间是隔离的. ...

  8. mysql 杀掉(kill) lock进程脚本

    杀掉lock进程最快的方法是重启mysql,像你这种情况,1000多sql锁住了,最好是重启如果不允许重启,我提供一个shell脚本,生成 kill id命令杀掉lock线程,如下:--------- ...

  9. 【SpringMVC学习10】SpringMVC对RESTfull的支持

    RESTful架构,就是目前流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用.RESTful架构对url进行规范,写RESTful格式的url是什么样子 ...

  10. c#关闭excel进程失败的解决方法

    解决方法如下: 1.运行命令dcomcnfg -32,打开组件服务 2.找到execl服务,属性中设置交互式用户 2.设置用户权限 3.设置IIS权限