Pull 解析和 Sax 解析很相似,都是轻量级的解析。在 Android 的内核中已经嵌入了 Pull,所以我们不需要再添加第三方 jar 包来支持 Pull。

Pull 解析和 Sax 解析不一样的地方有:

1)Pull 读取 XML 文件后触发相应的事件调用方法返回的是数字

2)Pull 可以在程序中控制想解析到哪里就可以停止解析

PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。

读取到xml的声明返回 START_DOCUMENT;

读取到xml的结束返回 END_DOCUMENT ;

读取到xml的开始标签返回 START_TAG;

读取到xml的结束标签返回 END_TAG;

读取到xml的文本返回 TEXT

PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术

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

这是我们的解析代码

   
   
   
   
  1. /** 
  2.      * 解析 
  3.      * */ 
  4.     public List parserXML(InputStream is) { 
  5.         // 创建一个list 用来保存解析的xml 
  6.         List persons = null
  7.  
  8.         Person person = null
  9.  
  10.         XmlPullParser parser = Xml.newPullParser(); 
  11.         try { 
  12.             parser.setInput(is, "utf-8"); 
  13.  
  14.             // 获取事件类型 
  15.             int event = parser.getEventType(); 
  16.             while (event != XmlPullParser.END_DOCUMENT) { 
  17.                 switch (event) { 
  18.                 case XmlPullParser.START_DOCUMENT: 
  19.                     // 当前事件是文档开始事件 
  20.                     // 文档开始时初始化list 
  21.                     persons = new ArrayList(); 
  22.                     break
  23.  
  24.                 case XmlPullParser.START_TAG: 
  25.                     // 当前事件是标签元素开始事件 
  26.                     if (parser.getName().equals("person")) { 
  27.                         // 如果是person标签 则新建person对象 并获取id 
  28.                         person = new Person(); 
  29.                         person.set_id(parser.getAttributeValue(0)); 
  30.                     } else if (parser.getName().equals("name")) { 
  31.                         // 判断当前标签是否是name 将值保存到person 
  32.                         //当某个元素开始时,可以调用 解析器实例的nextText() 从 XML 文档中提取所有字符数据 
  33.                         person.set_name(parser.nextText()); 
  34.                     } else if (parser.getName().equals("age")) { 
  35.                         person.set_age(parser.nextText()); 
  36.                     } 
  37.                     break
  38.                 case XmlPullParser.TEXT: 
  39.                      
  40.                     break
  41.                 case XmlPullParser.END_TAG: 
  42.                     // 当前事件是标签元素结束事件 
  43.                     if (parser.getName().equals("person")) { 
  44.                         // person标签结束 添加到list并设空person对象 
  45.                         persons.add(person); 
  46.                         person = null
  47.                     } 
  48.                     break
  49.                 default
  50.                     break
  51.                 } 
  52.                 // 进入下一个元素并触发相应事件 
  53.                 event = parser.next(); 
  54.  
  55.             } 
  56.  
  57.         } catch (Exception e) { 
  58.             // TODO Auto-generated catch block 
  59.             e.printStackTrace(); 
  60.         } 
  61.  
  62.         return persons; 
  63.     } 

 基本和sax的原理是差不多的   就不去细讲了


接下来讲解怎么通过PULL生成xml

使用到了XmlSerializer类

我们有两种方法去获取XmlSerializer对象

   
   
   
   
  1. // 方法1  
  2. XmlSerializer serializer = Xml.newSerializer();  
  3. // 方法2  
  4. XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
  5. XmlSerializer serializer = factory.newSerializer(); 

通过serializer的几个方法 来创建xml

首先  设置输出流对象

   
   
   
   
  1. serializer.setOutput(writer); 

接下来开始写入

   
   
   
   
  1. //standalone  用来表示该文件是否呼叫其它外部的文件。  
  2. serializer.startDocument("utf-8"true); 
  3. //start和end成对出现 
  4. serializer.endDocument(); 

startDocumentendDocument创建元素,使用startTag和endTag

   
   
   
   
  1. //同样的   start和end成对出现  
  2. serializer.startTag(null"persons");  
  3. serializer.endTag(null"persons");  

如果元素有属性怎么办?  使用下面的方法就添加了属性id

   
   
   
   
  1. serializer.attribute(null"id", person.get_id()); 

还有  元素需要添加值的时候  该怎么半?

   
   
   
   
  1. serializer.text(person.get_name()); 

到这里  讲的也就差不多了,接下来看下完整的生成方法

   
   
   
   
  1. public String createXML() { 
  2.  
  3.     List persons = getTestValues(); 
  4.  
  5.     // 方法1 
  6.     XmlSerializer serializer = Xml.newSerializer(); 
  7.     // 方法2 
  8.     // XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
  9.     // XmlSerializer serializer = factory.newSerializer(); 
  10.  
  11.     StringWriter writer = new StringWriter(); 
  12.     try { 
  13.         // 设置输出流对象   
  14.         serializer.setOutput(writer); 
  15.         serializer.startDocument("utf-8"true); 
  16.  
  17.         // 第一个参数为命名空间,如果不使用命名空间,可以设置为null 
  18.         serializer.startTag(null"persons"); 
  19.         for (int i = 0; i < persons.size(); i++) { 
  20.             Person person = persons.get(i); 
  21.             serializer.startTag(null"person"); 
  22.             serializer.attribute(null"id", person.get_id()); 
  23.  
  24.             serializer.startTag(null"name"); 
  25.             serializer.text(person.get_name()); 
  26.             serializer.endTag(null"name"); 
  27.  
  28.             serializer.startTag(null"age"); 
  29.             serializer.text(person.get_age()); 
  30.             serializer.endTag(null"age"); 
  31.  
  32.             serializer.endTag(null"person"); 
  33.         } 
  34.         serializer.endTag(null"persons"); 
  35.         serializer.endDocument(); 
  36.         return writer.toString(); 
  37.     } catch (Exception e) { 
  38.         // TODO Auto-generated catch block 
  39.         e.printStackTrace(); 
  40.     } 
  41.     return null

我们来调用下这个方法

   
   
   
   
  1. Toast.makeText(activity, new Pull().createXML(), 
  2.                     Toast.LENGTH_LONG).show(); 

下面就是显示效果  说明生成成功~

【Android网络开发の3】XML之PULL方式 解析和生成XML文件_第1张图片

Android平台的三个XML生成解析方式已经全部讲完