android 提供了三种解析xml的方式,分别是sax,dom,pull,
pull是android独有的,在以前Java学习中没有出现过,dom和sax java中一直使用,如dom4j就是使用的sax.
接下来我们学习sax在android系统中的学习。
第一步:我们编写一个person.xml文件放到classpath下,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>张三</name> <age>30</age> </person> <person id="20"> <name>李四</name> <age>25</age> </person> </persons>第二步:我们编写对应的Person.java 实体:
public class Person { private int id; private String name; private int age; getters(); setters();
第三步:编写解析代码,实现如下:
package com.hkrt.action; 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.hkrt.domain.Person; /** * 使用SAX (simple api for xml )解析xml * 基于事件驱动,不需要加载整个文件。 * @author Administrator */ public class SAXService { public List<Person> personService(InputStream inStream) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); PersonDefaultHandler handler = new PersonDefaultHandler(); parser.parse(inStream, handler); inStream.close(); return handler.getPersons(); } private final class PersonDefaultHandler extends DefaultHandler { /**记录解析后的所有person 集合*/ private List<Person> persons = null; private Person currentPerson; public List<Person> getPersons() { return persons; } @SuppressWarnings("unused") public void setPersons(List<Person> persons) { this.persons = persons; } //定义一个标记变量,标记当前的Xml文件被解析到哪个标签 private String tagName = null; //第一步执行的方法 @Override public void startDocument() throws SAXException { persons = new ArrayList<Person>(); } /** * 解析XML时,当开始读到一个元素标签开始时,执行下面方法 */ @Override public void startElement(String uri, String localName, String qName,Attributes attr) throws SAXException { //判断标签名是否为person,是的话创建一个Person对象,并将其id属性拿出来,赋值到person对象中 if ("person".equals(localName)) { currentPerson = new Person(); currentPerson.setId(Integer.parseInt(attr.getValue("id"))); } tagName = localName; } /** 解析XML时,当开始读到一个文本元素时,执行下面方法 */ @Override public void characters(char[] ch, int start, int length)throws SAXException { //判断此文本元素是在一个 有效的标签体里面的 例:正确:<name>文本元素</name> 错误: 文本元素<name></name> if (tagName != null) { String data = new String(ch, start, length); if ("name".endsWith(tagName)) { currentPerson.setName(data); } else if ("age".endsWith(tagName)) { currentPerson.setAge(Short.parseShort(data)); } } } /** * 解析XML时,当读到结束一个元素标签时,执行下面方法 */ @Override public void endElement(String uri, String localName, String qName)throws SAXException { if ("person".equals(localName)) { persons.add(currentPerson); currentPerson = null; } tagName = null; } } }
第四步:进行代码测试,我们这里使用android带的junit的实现,具体包已在android中集成,我们不需要额外添加。
- 在AndoirManifest.xml 添加junit测试环境: <uses-library android:name="android.test.runner" /> <instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="换成Activity 下的包" android:label="Tests for My App" /> - 编写测度代码
public class PersonTest extends AndroidTestCase { private static final String TAG="PersonTest"; public void testSAXService()throws Throwable{ SAXService saxservice=new SAXService(); InputStream inStream=this.getClass().getClassLoader().getResourceAsStream("person.xml"); List <Person> persons=saxservice.personService(inStream); for(Person p:persons){ Assert.assertNotNull(p);//junit 断言,不为空LogCat 输出的结果没找到 Log.i(TAG,p.toString());//LogCat 输出的结果是I System.err.println(p);//LogCat 输出的结果是W } } }
第五步:启动模拟器,进行Andoird JUnit Test 。
测试结果: