你的位置:首页 > Java教程

[Java教程]java拾遗3


使用PULL方式解析

Pull是STAX的一个实现

StAX是The Streaming API for

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

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

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

 

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

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

 

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

www.

 

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

选择合适的XPP3下载:

 

如,我下载了:

 

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

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

 

如同DOM和SAX解析

 

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

 

newPullParser()和newSerializer()方法分别用于获取

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

 

 

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

 

通过调用getEventType()方法,来确认当前解析

事件类型通过

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属性的值。

以上,是

 

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

 

startDocument()方法,指定

如:startDocument(“utf-8”, true);将在

<?

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

 

text()设置文本内容

 

endTage()结束一个节点。

 

attribute()设置节点的属性。

 

了解了这几个类的常用方法后,就可以实现PULL模式的

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

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

待解析的students.

 1 <??> 2  3 <students> 4  5   <student id="000"> 6  7     <name>zhangsan22</name> 8  9     <gender>female</gender>10 11     <age>26</age>12 13   </student>14 15   <student id="002">16 17     <name>lisi</name>18 19     <gender>male</gender>20 21     <age>24</age>22 23   </student>24 25   <student id="003">26 27     <name>xiaoqiao</name>28 29     <gender>female</gender>30 31     <age>18</age>32 33   </student>34 35   <student id="004">36 37     <name>diaochan</name>38 39     <gender>female</gender>40 41     <age>23</age>42 43   </student>44 45 </students>

对应的实体类:Student.java:

 1 package cn.csc.bean; 2  3 public class Student { 4  5     private String id = null; 6  7     private String name = null; 8  9     private String gender = null;10 11     private int age = 0;12 13     public String getId() {14 15          return id;16 17      }18 19     public void setId(String id) {20 21          this.id = id;22 23      }24 25     public String getName() {26 27          return name;28 29      }30 31     public void setName(String name) {32 33          this.name = name;34 35      }36 37     public String getGender() {38 39          return gender;40 41      }42 43     public void setGender(String gender) {44 45          this.gender = gender;46 47      }48 49     public int getAge() {50 51          return age;52 53      }54 55     public void setAge(int age) {56 57          this.age = age;58 59      }60 61     public Student(String id, String name, String gender, int age) {62 63          super();64 65          this.id = id;66 67          this.name = name;68 69          this.gender = gender;70 71          this.age = age;72 73      }74 75     public Student() {76 77          super();78 79      }80 81     public String toString() {82 83          return "[id:"+id+",name:"+name+",gender:"+gender+",age"+age+"]";84 85      }86 87 }

 

StudentPullUtils类,实现两个方法,一个用于将

 1 public class StudentPullUtils { 2  3     public static List<Student> parsethrows Exception{ 4  5          List<Student> list = new ArrayList<Student>(); 6  7            8  9           factory.newPullParser(); 10  11          parser.setInput(new FileInputStream(filename), "utf-8"); 12  13          int eventType; 14  15          Student s = null; 16  17          while((eventType = parser.getEventType())!=  18  19               if(eventType == )){ 20  21                   s = new Student(); 22  23                   s.setId(parser.getAttributeValue(0)); 24  25               } 26  27               if(eventType == )){ 28  29                    s.setName(parser.nextText()); 30  31               } 32  33               if(eventType == )){ 34  35                    s.setAge(Integer.parseInt(parser.nextText())); 36  37               } 38  39               if(eventType == )){ 40  41                    s.setGender(parser.nextText()); 42  43               } 44  45               if(eventType == )){ 46  47                    list.add(s); 48  49               } 50  51               parser.next(); 52  53           } 54  55          return list; 56  57      } 58  59      60  61     public static boolean serializeList(List<Student> list, String filename) throws Exception{ 62  63            64  65           factory.newSerializer(); 66  67          serializer.setOutput(new FileOutputStream(filename), "utf-8"); 68  69          serializer.startDocument("utf-8", true); 70  71          serializer.startTag(null, "students"); 72  73          for(Student s : list){ 74  75               serializer.startTag(null, "student"); 76  77               serializer.attribute(null, "id", s.getId()); 78  79               serializer.startTag(null, "name"); 80  81               serializer.text(s.getName()); 82  83               serializer.endTag(null, "name"); 84  85               serializer.startTag(null, "gender"); 86  87               serializer.text(s.getGender()); 88  89               serializer.endTag(null, "gender"); 90  91               serializer.startTag(null, "age"); 92  93               serializer.text(s.getAge()+""); 94  95               serializer.endTag(null, "age"); 96  97               serializer.endTag(null, "student"); 98  99           }100 101          serializer.endTag(null, "students");102 103           serializer.endDocument();104 105          106 107          return true;108 109      }110 111 }

 

调用测试:实现将数据从students.

1 List<Student> list = StudentPullUtils.parse);2 3 for(Student s: list){4 5     s.setAge(s.getAge()+1);6 7 }8 9 StudentPullUtils.serializeList(list, "students_bak.