Android 采用PULL来解析XML

概述:

PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。

PULL 的工作原理:

XML pull提供了开始元素和结束元素。当某个元素开始时,可以调用parsernextTextXML文档中提取所有字符数据。当解析到一个文档结束时,自动生成EndDocument事件。

常用的XML pull的接口和类:

XmlPullParser该解析器是一个在org.xmlpull.v1中定义的解析功能的接口。

XmlSerializer它是一个接口,定义了XML信息集的序列。

XmlPullParserFactory这个类用于在XMPULL V1 API中创建XML Pull解析器。

XmlPullParserException抛出单一的XML pull解析器相关的错误。

PULL解析器的运行方式和SAX类似,都是基于事件的模式。

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

读取到xml声明返回 START_DOCUMENT; 结束返回 END_DOCUMENT ; 开始标签返回 START_TAG;

结束标签返回 END_TAG; 文本返回 TEXT。

几种解析技术的比较与总结: 
对于Android的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。

DOM在处理XML文件时,将XML文件解析成树状结构并放入内存中进行处理。当XML文件较小时,我们可以选DOM,因为它简单、直观。

SAX则是以事件作为解析XML文件的模式,它将XML文件转化成一系列的事件,由不同的事件处理器来决定如何处理。XML文件较大时,选择SAX技术是比较合理的。虽然代码量有些大,但是它不需要将所有的XML文件加载到内存中。这样对于有限的Android内存更有效,而且Android提供了一种传统的SAX使用方法以及一个便捷的SAX包装器。 使用AndroidutilXml类,从示例中可以看出,会比使用 SAX来得简单。

XML pull解析并未像SAX解析那样监听元素的结束,而是在开始处完成了大部分处理。这有利于提早读取XML文件,可以极大的减少解析时间,这种优化对于连接速度较漫的移动设备而言尤为重要。对于XML文档较大但只需要文档的一部分时,XML Pull解析器则是更为有效的方法。


开发实例:

在asset定义了books.xml文件,对于它,只要是一份格式良好的xml文档即可,具体内容根据需要定义。

读取XML:从定义好的books.xml文件解析并显示出来;

写入XML:将解析后的内容再写入到本地,这里也保存为名字为books.xml的文件。



例如:books.xml定义如下形式:

01 <?xml version="1.0" encoding="utf-8"?>
02 <books>
03     <book>
04         <id>1001</id>
05         <name>Thinking In Java</name>
06         <price>80.00</price>
07     </book>
08     <book>
09         <id>1002</id>
10         <name>Core Java</name>
11         <price>90.00</price>
12     </book>
13     <book>
14         <id>1003</id>
15         <name>Hello, Andriod</name>
16         <price>100.00</price>
17     </book>
18 </books>


完整代码:

PULLParserActivity:

01 package com.xsjayz.xml;
02  
03 import java.io.FileOutputStream;
04 import java.io.InputStream;
05 import java.util.List;
06  
07 import android.app.Activity;
08 import android.content.Context;
09 import android.os.Bundle;
10 import android.util.Log;
11 import android.view.View;
12 import android.widget.Button;
13 import android.widget.TextView;
14  
15 /**
16  * PULL解析器,这里只是简单的定义了一个TextView显示解析结果,两个Button操作。
17  *
18  * @since 2012-08-23
19  */
20 public class PULLParserActivity extends Activity {
21      
22     private static final String TAG = "XML";
23     private TextView textView = null;
24     private Button readBtn = null;
25     private Button writeBtn = null;
26  
27     private BookParser parser;
28     private List<Book> booksList;
29  
30     @Override
31     public void onCreate(Bundle savedInstanceState) {
32         super.onCreate(savedInstanceState);
33         setContentView(R.layout.main);
34  
35         textView = (TextView) findViewById(R.id.txt);
36         readBtn = (Button) findViewById(R.id.read_btn);
37         writeBtn = (Button) findViewById(R.id.write_btn);
38  
39         readBtn.setOnClickListener(new View.OnClickListener() {
40             @Override
41             public void onClick(View v) {
42                 try {
43                     InputStream is = getAssets().open("books.xml");
44                     parser = new PULLBookParser();
45                     booksList = parser.parse(is);
46                      
47                     for (Book book : booksList) {
48                         Log.i(TAG, book.toString());
49                     }
50  
51                     for (Book book : booksList) {
52                         textView.setText(textView.getText() + book.toString());
53                     }
54                 catch (Exception e) {
55                     Log.e(TAG, e.getMessage());
56                 }
57             }
58         });
59  
60         writeBtn.setOnClickListener(new View.OnClickListener() {
61             @Override
62             public void onClick(View v) {
63                 try {
64                     String xmlString = parser.serialize(booksList); // 序列化
65                     FileOutputStream fos = openFileOutput("books.xml",
66                             Context.MODE_PRIVATE);
67                     fos.write(xmlString.getBytes("UTF-8"));
68                 catch (Exception e) {
69                     Log.e(TAG, e.getMessage());
70                 }
71             }
72         });
73     }
74 }

PULLBookParser:

001 package com.xsjayz.xml;
002  
003 import java.io.InputStream;
004 import java.io.StringWriter;
005 import java.util.ArrayList;
006 import java.util.List;
007  
008 import org.xmlpull.v1.XmlPullParser;
009 import org.xmlpull.v1.XmlSerializer;
010  
011 import android.util.Xml;
012  
013 /**
014  * PULL解析器,实现了BookParser接口
015  */
016 public class PULLBookParser implements BookParser {
017  
018     /**
019      * @param is
020      * @return booksList
021      */
022     @Override
023     public List<Book> parse(InputStream is) throws Exception {
024  
025         List<Book> booksList = null;
026         Book book = null;
027  
028         // 由android.util.Xml创建一个XmlPullParser实例
029         XmlPullParser parser = Xml.newPullParser();
030         // 设置输入流 并指明编码方式
031         parser.setInput(is, "UTF-8");
032         // 产生第一个事件
033         int eventType = parser.getEventType();
034  
035         while (eventType != XmlPullParser.END_DOCUMENT) {
036  
037             switch (eventType) {
038             // 判断当前事件是否为文档开始事件
039             case XmlPullParser.START_DOCUMENT:
040                 booksList = new ArrayList<Book>(); // 初始化books集合
041                 break;
042  
043             // 判断当前事件是否为标签元素开始事件
044             case XmlPullParser.START_TAG:
045  
046                 if (parser.getName().equals("book")) { // 判断开始标签元素是否是book
047                     book = new Book();
048                 else if (parser.getName().equals("id")) {
049                     eventType = parser.next();
050                     // 得到book标签的属性值,并设置book的id
051                     book.setId(Integer.parseInt(parser.getText()));
052                 else if(parser.getName().equals("name")) { // 判断开始标签元素是否是book
053                     eventType = parser.next();
054                     book.setName(parser.getText());
055                 else if(parser.getName().equals("price")) { // 判断开始标签元素是否是price
056                     eventType = parser.next();
057                     book.setPrice(Float.parseFloat(parser.getText()));
058                 }
059                 break;
060  
061             // 判断当前事件是否为标签元素结束事件
062             case XmlPullParser.END_TAG:
063                 if (parser.getName().equals("book")) { // 判断结束标签元素是否是book
064                     booksList.add(book); // 将book添加到books集合
065                     book = null;
066                 }
067                 break;
068             }
069             // 进入下一个元素并触发相应事件
070             eventType = parser.next();
071         }
072         return booksList;
073     }
074  
075     /**
076      * @param books
077      * @return writer.toString()
078      */
079     @Override
080     public String serialize(List<Book> books) throws Exception {
081  
082         // 由android.util.Xml创建一个XmlSerializer实例
083         XmlSerializer serializer = Xml.newSerializer();
084         StringWriter writer = new StringWriter();
085         // 设置输出方向为writer
086         serializer.setOutput(writer);
087         serializer.startDocument("UTF-8"true);
088         serializer.startTag("""books");
089  
090         for (Book book : books) {
091             serializer.startTag("""book");
092             serializer.attribute("""id", book.getId() + "");
093  
094             serializer.startTag("""name");
095             serializer.text(book.getName());
096             serializer.endTag("""name");
097  
098             serializer.startTag("""price");
099             serializer.text(book.getPrice() + "");
100             serializer.endTag("""price");
101  
102             serializer.endTag("""book");
103         }
104         serializer.endTag("""books");
105         serializer.endDocument();
106  
107         return writer.toString();
108     }
109 }

BookParser:

01 package com.xsjayz.xml;
02  
03 import java.io.InputStream;
04 import java.util.List;
05  
06 public interface BookParser {
07  
08     /**
09      * 解析输入流 得到Book对象集合
10      *
11      * @param is
12      * @throws Exception
13      */
14     public List<Book> parse(InputStream is) throws Exception;
15  
16     /**
17      * 序列化Book对象集合 得到XML形式的字符串
18      *
19      * @param books
20      * @throws Exception
21      */
22     public String serialize(List<Book> books) throws Exception;
23 }

Book:

01 package com.xsjayz.xml;
02  
03 /**
04  * Book的model类,定义了Book的所有状态,访问器和修改器,重写了toString方法
05  */
06 public class Book {
07  
08     private int id;
09     private String name;
10     private float price;
11  
12     public int getId() {
13         return id;
14     }
15  
16     public void setId(int id) {
17         this.id = id;
18     }
19  
20     public String getName() {
21         return name;
22     }
23  
24     public void setName(String name) {
25         this.name = name;
26     }
27  
28     public float getPrice() {
29         return price;
30     }
31  
32     public void setPrice(float price) {
33         this.price = price;
34     }
35  
36     @Override
37     public String toString() {
38         return "id:" + id + "\nname:" + name + "\nprice:" + price + "\n";
39     }
40 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值