当前位置:编程学习 > XML/UML >>

Android学习之使用SAX解析xml文件

Android上经常使用xml来传递和交换数据。SAX(Simple API for XML)作为一种解析速度快并且占用内存少的xml解析器,非常适合Android等移动设备。SAX解析采用事件驱动,会判断当前读取到的字符是否符合xml语法中的某部分,从而触发相应事件。xml中的节点分为2种类型,分别是Element Node(元素节点)和Text Node(文本节点)。对于元素节点,当读取到开始标签时会触发startElement事件,当读取到结束标签时会触发endElement事件。对于文本节点,当读取到文本时会触发characters事件。另外,xml文档开始和结束时会分别触发startDocument和endDocument事件。所谓事件其实就是一些回调方法,这些方法定义在ContentHandler接口中,用SAX解析一个xml文件主要也就是要根据xml文件的节点等信息编写一个实现ContentHandler接口的实现类。
 
以下会用SAX解析这个test.xml文件,并用AndroidTextCase测试结果是否正确。
text.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>liming</name>
<age>30</age>
</person>
<person id="20">
<name>lixiang</name>
<age>25</age>
</person>
</persons>
过程如下:
在Eclipse下新建一个Android项目xml01
新建text.xml文件,放在src目录下面
新建一个JavaBean:Person,属性有id、name、age
编写一个业务类:SAXPersonService,解析test.xml文件,这里重点是根据test.xml文件中的节点名称等信息编写SAXParserHandler这个内部类,代码如下:
package com.study.service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.study.bean.Person;
/**
 * 使用SAX解析text.xml文件
 * @author Administrator
 *
 */
public class SAXPersonService {
 public List<Person> getPersons(InputStream inputStream) throws Throwable{
  SAXParserFactory factory = SAXParserFactory.newInstance();
  SAXParser parser = factory.newSAXParser();
  SAXParserHandler handler = new SAXParserHandler();
  parser.parse(inputStream, handler);
  return handler.getPersons();
 }
 
 private final class SAXParserHandler extends DefaultHandler{
 
  private List<Person> persons;
  // 记录正在访问的文本节点的前一个节点名称
  private String tag;
  private Person person;
 
  public List<Person> getPersons() {
   return persons;
  }
  @Override
  public void characters(char[] ch, int start, int length)
    throws SAXException {
   if(tag != null){
    if("name".equals(tag)){
     // 根据文本节点取值设置name
     person.setName(new String(ch, start, length));
    }else if("age".equals(tag)){
     // 根据文本节点取值设置age
     person.setAge(Integer.parseInt(new String(ch, start, length)));
    }
   }
  }
  @Override
  public void endElement(String uri, String localName, String qName)
    throws SAXException {
   // localName是不带命名空间前缀的标签名
   if("person".equals(localName)){
    // 将person对象加入到集合中
    persons.add(person);
    // person对象设置为null
    person = null;
   }
  
   // 节点结束时一定要将tag设置为null
   // 否则会将空白字符赋值给name和age,从而出错
   tag = null;
  }
  @Override
  public void startDocument() throws SAXException {
   persons = new ArrayList<Person>();
  }
  @Override
  public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
   // localName是不带命名空间前缀的标签名
   if("person".equals(localName)){
    person = new Person();
    // 通过索引查找属性的值
    person.setId(Integer.parseInt(attributes.getValue(0)));
   }
  
   tag = localName;
  }
 
 }
}
 
在AndroidManifest.xml加入Android测试所需要的组件
<uses-library android:name="android.test.runner" />
以及
<instrumentation android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="com.study.action" android:label="Tests for My App" />
编写一个AndroidTestCase:SAXPersonServiceTest,测试代码如下:
package com.study.action;
import java.io.InputStream;
import java.util.List;
import android.test.AndroidTestCase;
import android.util.Log;
import com.study.bean.Person;
import com.study.service.SAXPersonService;
public class SAXPersonServiceTest extends AndroidTestCase {
 private static final String TAG = "SAXPersonServiceTest";
 public void testGetPersons() throws Throwable{
  SAXPersonService personService = new SAXPersonService();
  InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("test.xml");
  List<Person> persons = personService.getPersons(inputStream);
  for(Person person : persons){
   Log.i(TAG, person.getId() + ", " + person.getName() + ", " + person.getAge());
  }
 }
}
输入日志,运行结果如下:

作者“新的启程”

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,