首页 > 代码库 > Android开发之使用PULL解析和生成XML

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

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解析的过程吧。

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

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开发之解析XML并实现三级联动效果 

 

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