Android开发之使用PULL解析和生成XML

来源:互联网 发布:linux输入法 编辑:程序博客网 时间:2024/05/04 15:10

Android开发之使用PULL解析和生成XML

请尊重他人的劳动成果,转载请注明出处:Android开发之使用PULL解析和生成XML

一、使用PULL解析XML

1.PULL简介

我曾在《浅谈XMl解析的几种方式》一文中介绍了使用DOM方式,SAX方式,Jdom方式,以及dom4j的方式来解析XML。除了可以使用以上方式来解析XML文件外,也可以使用android系统内置的Pull解析器来解析XML文件。 Pull解析器的运行方式与SAX解析器相似。它提供了类似的事件,如开始元素和结束元素事件。使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行选择,然后进行相应处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型元素的值。

2.  特点

(1)简单的结构:一个接口,一个例外,一个工厂组成了 Pull解析器。

(2)简单易用Pull解析器只有一个重要的方法next(),它被用来检索下一个事件。而它的事件也仅仅只有5个。

Ø START DOCUMENT

Ø START_TAG

Ø TEXT

Ø END_TAG

Ø END_DOCUMENT

(3)多功能性:通用的XML解析器和多种实现,并具有可扩展性。

(4)最小的需求:为了与JavaME兼容和在小型设备上运作而设计,并允许创建占用非常小的内存的XMLPULL解析器。

3.  工作原理

解析XML内容的方式与SAX是相似的,同样包括开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。但是它们不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而Pull解析器并没有强制要求提供触发的方法。因为它触发的事件并不是一个方法,而是一个数字。至于触发的事件要不要处理,由程序员自己决定。

XmlPull解析流程

看到这里,读者应该明白,为什么Pull解析器会被集成Android里了吧。并且Pull解析器,也可以用在JavaEE等非Android项目中,不一定只拘泥于Android的开发。下面我们通过一个示例来理解一下Pull解析的过程吧。

[java] view plain copy
print?
  1. public static List<Person> getPersons(InputStream inStream) throws Exception{  
  2.     Person person = null;  
  3.     List<Person> persons = null;  
  4.     XmlPullParser pullParser = Xml.newPullParser();  
  5.     pullParser.setInput(inStream, ”UTF-8”);  
  6.     int event = pullParser.getEventType();//触发第一个事件  
  7.     while(event!=XmlPullParser.END_DOCUMENT){  
  8.         switch (event) {  
  9.         case XmlPullParser.START_DOCUMENT:  
  10.             persons = new ArrayList<Person>();  
  11.             break;  
  12.         case XmlPullParser.START_TAG:  
  13.             if(“person”.equals(pullParser.getName())){  
  14.                 int id = new Integer(pullParser.getAttributeValue(0));  
  15.                 person = new Person();  
  16.                 person.setId(id);  
  17.             }  
  18.             if(person!=null){  
  19.                 if(“name”.equals(pullParser.getName())){  
  20.                     person.setName(pullParser.nextText());  
  21.                 }  
  22.                 if(“age”.equals(pullParser.getName())){  
  23.                     person.setAge(new Short(pullParser.nextText()));  
  24.                 }  
  25.             }  
  26.             break;  
  27.              
  28.         case XmlPullParser.END_TAG:  
  29.             if(“person”.equals(pullParser.getName())){  
  30.                 persons.add(person);  
  31.                 person = null;  
  32.             }  
  33.             break;  
  34.         }  
  35.         event = pullParser.next();  
  36.     }  
  37.     return persons;  
  38. }  
public static List<Person> getPersons(InputStream inStream) throws Exception{    Person person = null;    List<Person> persons = null;    XmlPullParser pullParser = Xml.newPullParser();    pullParser.setInput(inStream, "UTF-8");    int event = pullParser.getEventType();//触发第一个事件    while(event!=XmlPullParser.END_DOCUMENT){        switch (event) {        case XmlPullParser.START_DOCUMENT:            persons = new ArrayList<Person>();            break;        case XmlPullParser.START_TAG:            if("person".equals(pullParser.getName())){                int id = new Integer(pullParser.getAttributeValue(0));                person = new Person();                person.setId(id);            }            if(person!=null){                if("name".equals(pullParser.getName())){                    person.setName(pullParser.nextText());                }                if("age".equals(pullParser.getName())){                    person.setAge(new Short(pullParser.nextText()));                }            }            break;        case XmlPullParser.END_TAG:            if("person".equals(pullParser.getName())){                persons.add(person);                person = null;            }            break;        }        event = pullParser.next();    }    return persons;}


代码说明:

1)int event =pullParser.getEventType();Pull解析器的第一个事件。读者可以看到,这个方法的返回值是int类型的,这就是前面所提到的Pull解析器返回的是一个数字,类似于一个信号。那么这些信号都代表什么意思呢? Pull解析器已经定义了这五个常量,而且对于事件,仅仅只有这5个,如下:

    XmlPullParser.START_DOCUMENT (开始解析,只执行一次);

    XmlPullParser.START_TAG (开始元素)

    XmlPullParser.TEXT (解析文本);

    XmlPullParser END_TAG (结束元素);

    XmlPullParser END_DOCUMENT (结束解析,只执行一次)。

2 )parser.getEventType()”触发了第一个事件,根据XML的语法,也就是从它开始了解析文档。那么,怎么样触发下一个事件呢?要通过Parser中最重要的方法:

parser.next();

注意:该方法是有返回值的,在Pull触发下—个事件的同时,也获得该事件的“信号”。通过获得的信号进行switch操作。

3)parsergetAttribiiteValue()”获得相应属性的值。它有两种形式,可以通过属性的索引,也可以通过(命名空间,属性名)进行索引。

二、使用PULL生成XML

[java] view plain copy
print?
  1. public static void save(List<Person> persons, OutputStream outStream) throws Exception{  
  2.     XmlSerializer serializer = Xml.newSerializer();  
  3.     serializer.setOutput(outStream, ”UTF-8”);  
  4.     serializer.startDocument(”UTF-8”true);  
  5.     serializer.startTag(null“persons”);  
  6.     for(Person person : persons){  
  7.        serializer.startTag(null“person”);  
  8.        serializer.attribute(null“id”, person.getId().toString());  
  9.        serializer.startTag(null“name”);  
  10.        serializer.text(person.getName());  
  11.        serializer.endTag(null“name”);  
  12.         
  13.        serializer.startTag(null“age”);  
  14.        serializer.text(person.getAge().toString());  
  15.        serializer.endTag(null“age”);  
  16.         
  17.        serializer.endTag(null“person”);  
  18.     }       
  19.     serializer.endTag(null“persons”);  
  20.     serializer.endDocument();  
  21.     outStream.flush();  
  22.     outStream.close();  
  23. }  
public static void save(List<Person> persons, OutputStream outStream) throws Exception{    XmlSerializer serializer = Xml.newSerializer();    serializer.setOutput(outStream, "UTF-8");    serializer.startDocument("UTF-8", true);    serializer.startTag(null, "persons");    for(Person person : persons){       serializer.startTag(null, "person");       serializer.attribute(null, "id", person.getId().toString());       serializer.startTag(null, "name");       serializer.text(person.getName());       serializer.endTag(null, "name");       serializer.startTag(null, "age");       serializer.text(person.getAge().toString());       serializer.endTag(null, "age");       serializer.endTag(null, "person");    }         serializer.endTag(null, "persons");    serializer.endDocument();    outStream.flush();    outStream.close();}

说明:

(1 ) XmlSerializCTserializer= Xml.newSerializer()定义了一个接口来实现 XML信息的串行化。那串行化又是什么呢?其也叫做对象的序列化,并不仅仅是简单地把对象保存在存储器上,它还可以使我们以二进制方式通过网络传输对象,使对象变得可以像基本数据一样传递。之后可以通过反串行化从这些连续的字节(byte)数据重新构建一个与原始对象状态相同的对象。

(2)定义一个方法,第一个参数是要生成XML文件的内容,第二个参教是一个写入器。 Write (写入器)接口要比输出流更加灵活。它可以向更多的媒介进行榆出,比如向硬盘、内存、网络等进行输出。“new一个持久化的XML对象。在这里,应该明白为什么要持久化,说白了就是一种写入硬盘的行为。

serializer.setOutput(writer);

设置了输出的方向。它接收两种类型的输出,分别是输出流和写入器。这点用到了刚才向读者介绍的writer写入器。

(3)XML中标签的成对出现,有开始,必有结束。所以在写入一个satrtTag()时,笔者习惯紧跟着写入与之相对应的endTag()。这样不至于在复杂的生成结构时,弄错了XML生成结构。

方法说明:第一个參数是XML的命名空间,第二个是标签名,endTag()相同。

:

Android开发

 

原创粉丝点击