Android(安卓)SAX方式解析XML文件
16lz
2021-01-25
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 ,它实现了这个接口,但是其所有的方法体都为空,在实现的时候,你只需 要继承这个类,然后重载相应的方法即可。使用 SAX 解析 itcast.xml 的代码如下: public static List<Person> readXML(InputStream inStream) { try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); // 创建解析器 // 设置解析器的相关特性, http://xml.org/sax/features/namespaces = true 表示开启命名空间特性 saxParser.setProperty("http://xml.org/sax/features/namespaces",true); XMLContentHandler handler = new XMLContentHandler(); saxParser.parse(inStream, handler); inStream.close(); return handler.getPersons(); } catch (Exception e) { e.printStackTrace(); } return null; } SAX 支持已内置到 JDK1.5 中,你无需添加任何的 jar 文件。关于 XMLContentHandler 的代码实现请看本页下面备 注。 l AndroidManifest.xml: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.gao.xml" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="android.test.runner" /> <activity android:name=".XMLParser" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.gao" android:label="Test for my app" /> </manifest> com.gao.domain.Person.java: package com.gao.domain; public class Person { private Integer id; private String name; private Integer age; public Person() { // TODO Auto-generated constructor stub } public Person(String name, Integer age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "id:"+id+",name:"+name+",age:"+age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } com.gao.service.SAXPersonService.java: package com.gao.service; import java.io.InputStream; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import com.gao.domain.Person; public class SAXPersonService { public static List<Person> readXML(InputStream inputStream) throws Exception{ SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); SAXParser saxParser=saxParserFactory.newSAXParser(); XMLContentHandler contentHandler=new XMLContentHandler(); saxParser.parse(inputStream, contentHandler); inputStream.close(); return contentHandler.getPersons(); } } com.gao.service.XMLContentHandler.java: package com.gao.service; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.gao.domain.Person; public class XMLContentHandler extends DefaultHandler{ private List<Person> persons; private Person person; private String preTag; public List<Person> getPersons() { return persons; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (person!=null) { String data=new String(ch,start,length); if ("name".equals(preTag)) { person.setName(data); }else if ("age".equals(preTag)) { person.setAge(new Integer(data)); } } } @Override public void startDocument() throws SAXException { persons=new ArrayList<Person>(); } @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if ("person".equals(localName)) { person=new Person(); person.setId(new Integer(attributes.getValue("id"))); } preTag=localName; } @Override public void endElement(String uri, String localName, String name) throws SAXException { if ("person".equals(localName)&&person!=null) { persons.add(person); person=null; } preTag=null; } } com.gao.test.SAXPersonServiceTest.java: package com.gao.test; import java.io.InputStream; import java.util.List; import android.test.AndroidTestCase; import android.util.Log; import com.gao.domain.Person; import com.gao.service.SAXPersonService; public class SAXPersonServiceTest extends AndroidTestCase{ private static final String TAG = "SAXPersonServiceTest"; public SAXPersonServiceTest() { // TODO Auto-generated constructor stub } public void testReadXML() throws Exception { InputStream inputStream=SAXPersonServiceTest.class.getClassLoader().getResourceAsStream("gao.xml"); List<Person> persons=SAXPersonService.readXML(inputStream); for (Person person : persons) { Log.i(TAG, person.toString()); } } } gao.xml: <?xml version="1.0" encoding="UTF-8"?> <persons> <person id="12"> <name>Gao</name> <age>23</age> </person> <person id="34"> <name>高</name> <age>34</age> </person> </persons> 刚开始进行单元测试的时候老是出现: [2011-02-27 12:42:58 - XMLParser] Launching instrumentation android.test.InstrumentationTestRunner on device emulator-5554 [2011-02-27 12:42:58 - XMLParser] Collecting test information [2011-02-27 12:43:20 - XMLParser] Test run failed: Unable to find instrumentation target package: com.gao.test 原来是自己刚开始在AndroidManifest.xml里面配置单元测试的时候包写错了: <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.gao.test" android:label="Test for my app" /> 包多加了一个test
更多相关文章
- 安全新手入坑——HTML标签
- Android坐标的简单方法介绍
- 创建点对点WiFi直连——翻译自developer.android.com Training
- android接口回调的两中简单写法
- 应该是史上最全最新Java和Android面试题目(自己总结和收集的)
- android面试2
- 吐血总结 2020 Android(安卓)实习面经
- activity使用theme.dialog且activity中有dialog时按返回按钮dial
- android根据经纬度查询位置名称