android xml解析之SAX

在Android平台上可以使用Simple API for XML(SAX) 、 Document Object Model(DOM)和Android附带的pull解析器解析XML文件。 下面是本例子要解析的XML文件:

文件名称:itcast.xml
<?xml version="1.0" encoding="UTF-8"?>
<persons>
 <person id="23">
  <name>liming</name>
  <age>30</age>
 </person>
 <person id="20">
  <name>lixiangmei</name>
  <age>25</age>
 </person>
</persons>

例子定义了一个javabean用于存放上面解析出来的xml内容, 这个javabean为Person。javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set方法

SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。下面是一些ContentHandler接口常用的方法:
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument()
和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。 
startElement(String namespaceURI, String localName, String qName, Attributes atts) 
当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
endElement(String uri, String localName, String name)
这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length) 
这个方法用来处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。

只要为SAX提供实现ContentHandler接口的类,那么该类就可以得到通知事件(实际上就是SAX调用了该类中的回调方法)。因为ContentHandler是一个接口,在使用的时候可能会有些不方便,因此,SAX还为其制定了一个Helper类:DefaultHandler,它实现了ContentHandler接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重写相应的方法即可。

下面来看具体的实例:

首先建一个itcast.xml文件在src目录下,然后新建一个cn.itcast.domain包,在包下新建一个person类,主要用于存放上面解析出来的xml内容,javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set方法

具体代码如下:

复制代码
 1 package cn.itcast.domain;
 2 
 3 public class Person {
 4     private Integer id;
 5     private String name;
 6     private Short age;
 7     
 8     public Person(){}
 9     
10     public Person(Integer id, String name, Short age) {
11         this.id = id;
12         this.name = name;
13         this.age = age;
14     }
15     
16     public Integer getId() {
17         return id;
18     }
19     public void setId(Integer id) {
20         this.id = id;
21     }
22     public String getName() {
23         return name;
24     }
25     public void setName(String name) {
26         this.name = name;
27     }
28     public Short getAge() {
29         return age;
30     }
31     public void setAge(Short age) {
32         this.age = age;
33     }
34     @Override
35     public String toString() {
36         return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";
37     }
38     
39 }
复制代码

第二步:新建一个package cn.itcast.service包,在包下新建一个SAXPersonService类,这个就是MVC里的M,业务类,主要代码如下

复制代码
 1 package cn.itcast.service;
 2 
 3 import java.io.InputStream;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 import javax.xml.parsers.SAXParser;
 7 import javax.xml.parsers.SAXParserFactory;
 8 import org.xml.sax.Attributes;
 9 import org.xml.sax.SAXException;
10 import org.xml.sax.helpers.DefaultHandler;
11 
12 import cn.itcast.domain.Person;
13 /**
14  * 采用SAX解析XML内容
15  */
16 public class SAXPersonService {
17     
18     public List<Person> getPersons(InputStream inStream) throws Throwable{
19         //得到一个Sax解析器工厂
20         SAXParserFactory factory = SAXParserFactory.newInstance();
21         //得到解析器
22         SAXParser parser = factory.newSAXParser();
23         //new出一个PersonParser对象出来。把这个对象传到下面语句中
24         PersonParser personParser = new PersonParser();
25         //对得到的输入流Sax进行解析,第一个参数是要进行解析的xml内容,第二个参数是给 SAX DefaultHandler使用(回调函数)
26         parser.parse(inStream, personParser);
27         inStream.close();
28         //返回得到的getPersons
29         return personParser.getPersons();
30     }
31 
32     private final class PersonParser extends DefaultHandler{
33         //把解析到的数据都放到集合里面去
34         private List<Person> persons = null;
35         //记录当前所解析到的元素节点名称
36         private String tag = null;
37         private Person person = null;
38         //提供一个getpersons方法,主要是为主程序使用
39         public List<Person> getPersons() {
40             return persons;
41         }
42 
43         @Override
44         public void startDocument() throws SAXException {
45             //初始化
46             persons = new ArrayList<Person>();
47         }
48         
49         @Override
50         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
51             //判断是不是我们要解析的元素节点
52             if("person".equals(localName)){
53                 person = new Person();//new出person对象,把要解析的内容传给person的Id属性
54                 person.setId(new Integer(attributes.getValue(0)));
55             }
56             //存放节点名称到成员变量里面
57             tag = localName;
58         }
59         
60         @Override
61         public void characters(char[] ch, int start, int length)
62                 throws SAXException {
63             //首先判断节点名称是否为空,然后在判断节点名称是否为name
64             if(tag!=null){
65                 String data = new String(ch, start, length);//获取文本节点的数据
66                 if("name".equals(tag)){//判断节点名称是否为name
67                     person.setName(data);//把要解析的内容传给person的name属性
68                 }else if("age".equals(tag)){//判断节点名称是否为age
69                     person.setAge(new Short(data));
70                 }
71             }
72         }
73 
74         @Override
75         public void endElement(String uri, String localName, String qName)
76                 throws SAXException {
77             if("person".equals(localName)){//当跟末节点为person时
78                 persons.add(person);//把person放到集合persons里面
79                 person = null;//把当前person设为空
80             }
81             //遇到结束元素就把记录设为空
82             tag = null;
83         }
84     }
85 }
复制代码

第三步:在主包下新建一个PersonServiceTest类,这个类相当与mvc中的c(控制层),主要是对SAXPersonService这个类进行单元测试

复制代码
 1 public class PersonServiceTest extends AndroidTestCase {
 2     private static final String TAG = "PersonServiceTest";
 3 
 4     public void testSAXGetPersons() throws Throwable{
 5         //new出一个业务对象
 6         SAXPersonService service = new SAXPersonService();
 7         //通过类加载器加载要解析的文件
 8         InputStream inStream = getClass().getClassLoader().getResourceAsStream("itcast.xml");
 9         List<Person> persons = service.getPersons(inStream);
10         for(Person person : persons){
11             Log.i(TAG, person.toString());    
12         }
13     }
14
复制代码

AndroidMainFest文件代码,这里主要是用到了单元测试,需要加几句代码

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3       package="cn.itcast.xml"
 4       android:versionCode="1"
 5       android:versionName="1.0">
 6     <application android:icon="@drawable/icon" android:label="@string/app_name">
 7          <uses-library android:name="android.test.runner" />
 8         <activity android:name=".MainActivity"
 9                   android:label="@string/app_name">
10             <intent-filter>
11                 <action android:name="android.intent.action.MAIN" />
12                 <category android:name="android.intent.category.LAUNCHER" />
13             </intent-filter>
14         </activity>
15 
16     </application>
17     <uses-sdk android:minSdkVersion="8" />
18 <instrumentation android:name="android.test.InstrumentationTestRunner"
19   android:targetPackage="cn.itcast.xml" android:label="Tests for My App" />
20 </manifest> 
复制代码

 

测试结果


这样,xml解析就完成了


转自http://www.cnblogs.com/shaoyangjiang/archive/2012/03/11/2389822.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值