博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android(三)数据存储之XML解析技术
阅读量:4069 次
发布时间:2019-05-25

本文共 14453 字,大约阅读时间需要 48 分钟。

<p>今日继续学习Android中使用Pull的XML解析技术实现对XML文件的解析和创建。由于明天休息,时间比较充裕,所以我也将昨天未总结的SAX解析技术在此做个总结。 </p>
<p><strong>一、SAX解析技术</strong></p>
<p>Sax使用的是事件驱动的流式解析技术。事件驱动的流式解析方式是,从文件的开始顺序解析到文档的结束,不可暂停或倒退。当解析到文档的开始或结束、元素的开始或结束等都会触发一个事件,我们在事件处理方法中完成对数据的操作。由此可见,我们需要编写实现了事件接口的类。</p>
<p><strong>1.</strong><strong>创建Android工程(eclipse3.5):</strong></p>
<p>Project name:AndroidXML</p>
<p>BuildTarget:Android2.1</p>
<p>Application name:Android XML 解析技术</p>
<p>Package name:com.changcheng.androidxml</p>
<p>Create Activity:AndroidXML</p>
<p>Min SDK Version:7</p>
<p><strong>2.</strong><strong>需要解析的XML文件:</strong></p>
<p><!--l version=<-->"1.0" encoding=<em>"UTF-8"</em>?></p>
<p></p>
<p>"23"></p>
<p>C++ Primer 4</p>
<p>78</p>
<p></p>
<p>"20"></p>
<p>Think in Java</p>
<p>76</p>
<p></p>
<p></p>
<p><strong></strong>该文件存放于src源码目录。</p>
<p><strong>3.XML</strong><strong>文件对应的实体Book:</strong></p>
<p><strong>package</strong> com.changcheng.androidxml.entity;</p>
<p><strong>public</strong> <strong>class</strong> Book {</p>
<p><strong>private</strong> <strong>int</strong> id;</p>
<p><strong>private</strong> String name;</p>
<p><strong>private</strong> <strong>float</strong> price;</p>
<p><strong>public</strong> Book() {</p>
<p>}</p>
<p><strong>public</strong> Book(<strong>int</strong> id, String name, <strong>float</strong> price) {</p>
<p><strong>this</strong>.id = id;</p>
<p><strong>this</strong>.name = name;</p>
<p><strong>this</strong>.price = price;</p>
<p>}</p>
<p><strong>public</strong> <strong>int</strong> getId() {</p>
<p><strong>return</strong> id;</p>
<p>}</p>
<p><strong>public</strong> <strong>void</strong> setId(<strong>int</strong> id) {</p>
<p><strong>this</strong>.id = id;</p>
<p>}</p>
<p><strong>public</strong> String getName() {</p>
<p><strong>return</strong> name;</p>
<p>}</p>
<p><strong>public</strong> <strong>void</strong> setName(String name) {</p>
<p><strong>this</strong>.name = name;</p>
<p>}</p>
<p><strong>public</strong> <strong>float</strong> getPrice() {</p>
<p><strong>return</strong> price;</p>
<p>}</p>
<p><strong>public</strong> <strong>void</strong> setPrice(<strong>float</strong> price) {</p>
<p><strong>this</strong>.price = price;</p>
<p>}</p>
<p>@Override</p>
<p><strong>public</strong> String toString() {</p>
<p><strong>return</strong> "Book [name=" + name + ", price=" + price + "]";</p>
<p>}</p>
<p>}</p>
<p><strong>4.Sax</strong><strong>解析XML的事件处理类:</strong></p>
<p>Sax的事件处理类必须实现ContentHandler接口,但我们在这个例子中不需要使用到ContentHandler接口的所有方法,我们仅需要其中的3个方法。所以Sax为我们提供了一个没有进行任何操作的ContentHandler实现类DefaultHandler。我们直接继承DefaultHandler类,并重写我们需要的方法即可。</p>
<p><strong>package</strong> com.changcheng.androidxml.xml;</p>
<p><strong>import</strong> java.util.ArrayList;</p>
<p><strong>import</strong> java.util.List;</p>
<p><strong>import</strong> org.xml.sax.Attributes;</p>
<p><strong>import</strong> org.xml.sax.SAXException;</p>
<p><strong>import</strong> org.xml.sax.helpers.DefaultHandler;</p>
<p><strong>import</strong> com.changcheng.androidxml.entity.Book;</p>
<p><strong>public</strong> <strong>class</strong> SaxXmlContentHandler <strong>extends</strong> DefaultHandler {</p>
<p><strong>private</strong> List books;</p>
<p><strong>private</strong> Book book;</p>
<p><strong>private</strong> String tagName;</p>
<p><strong>public</strong> List getBooks() {</p>
<p><strong>return</strong> books;</p>
<p>}</p>
<p>/**</p>
<p>* 接收文档的开始的通知。</p>
<p>*/</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> startDocument() <strong>throws</strong> SAXException {</p>
<p><strong>this</strong>.books = <strong>new</strong> ArrayList();</p>
<p>}</p>
<p>/**</p>
<p>* 接收字符数据的通知。</p>
<p>*/</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> characters(<strong>char</strong>[] ch, <strong>int</strong> start, <strong>int</strong> length)</p>
<p><strong>throws</strong> SAXException {</p>
<p><strong>if</strong> (<strong>this</strong>.tagName != <strong>null</strong>) {</p>
<p>String data = <strong>new</strong> String(ch, start, length);</p>
<p><strong>if</strong> (<strong>this</strong>.tagName.equals("name")) {</p>
<p><strong>this</strong>.book.setName(data);</p>
<p>} <strong>else</strong> <strong>if</strong> (<strong>this</strong>.tagName.equals("price")) {</p>
<p><strong>this</strong>.book.setPrice(Float.<em>parseFloat</em>(data));</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>/**</p>
<p>* 接收元素开始的通知。</p>
<p>* namespaceURI:元素的命名空间</p>
<p>* localName:元素的本地名称(不带前缀)</p>
<p>* qName:元素的限定名(带前缀)</p>
<p>* <span style="text-decoration: underline;">atts</span>:元素的属性集合</p>
<p>*/</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> startElement(String uri, String localName, String qName,</p>
<p>Attributes attributes) <strong>throws</strong> SAXException {</p>
<p><strong>if</strong> (localName.equals("book")) {</p>
<p>book = <strong>new</strong> Book();</p>
<p>book.setId(Integer.<em>parseInt</em>(attributes.getValue(0)));</p>
<p>}</p>
<p><strong>this</strong>.tagName = localName;</p>
<p>}</p>
<p>/**</p>
<p>* 接收文档的结尾的通知。</p>
<p>* <span style="text-decoration: underline;">uri</span>:元素的命名空间</p>
<p>* localName:元素的本地名称(不带前缀)</p>
<p>* name:元素的限定名(带前缀)</p>
<p>*/</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> endElement(String uri, String localName, String qName)</p>
<p><strong>throws</strong> SAXException {</p>
<p><strong>if</strong> (localName.equals("book")) {</p>
<p><strong>this</strong>.books.add(<strong>this</strong>.book);</p>
<p>}</p>
<p><strong>this</strong>.tagName = <strong>null</strong>;</p>
<p>}</p>
<p>}</p>
<p><strong>5.</strong><strong>编写测试Sax解析XML的类</strong></p>
<p>在创建工程时,生成的AndroidXML.java,并没有被使用到。因为我们使用Android的单元测试,运行上面的程序。</p>
<p>编写Android单元测试类:</p>
<p><strong>package</strong> com.changcheng.androidxml.test;</p>
<p><strong>import</strong> java.io.InputStream;</p>
<p><strong>import</strong> java.io.StringWriter;</p>
<p><strong>import</strong> java.util.ArrayList;</p>
<p><strong>import</strong> java.util.List;</p>
<p><strong>import</strong> com.changcheng.androidxml.entity.Book;</p>
<p><strong>import</strong> com.changcheng.androidxml.xml.AndoridSaxXml;</p>
<p><strong>import</strong> com.changcheng.androidxml.xml.AndroidPullXML;</p>
<p><strong>import</strong> android.test.AndroidTestCase;</p>
<p><strong>import</strong> android.util.Log;</p>
<p><strong>public</strong> <strong>class</strong> TestAndroidXML <strong>extends</strong> AndroidTestCase {</p>
<p><strong>private</strong> <strong>static</strong> <strong>final</strong> String <em>TAG</em> = "TestAndroidXML";</p>
<p>/**</p>
<p>* 测试<span style="text-decoration: underline;">Sax</span>解析XML</p>
<p>* <strong>@throws</strong> Throwable</p>
<p>*/</p>
<p><strong>public</strong> <strong>void</strong> testAndroidSaxReadXML() <strong>throws</strong> Throwable{</p>
<p>InputStream file = <strong>this</strong>.getClass().getClassLoader().getResourceAsStream("books.xml");</p>
<p><strong>try</strong> {</p>
<p>List books = AndoridSaxXml.<em>readXML</em>(file);</p>
<p>Log.<em>i</em>(<em>TAG</em>, books.toString());</p>
<p>} <strong>catch</strong> (Exception e) {</p>
<p>Log.<em>e</em>(<em>TAG</em>, e.toString());</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>测试类必须继承自AndroidTestCase类,Android的单元测试使用的是JUnit3,所以在我们的测试方法名称要以test开头。</p>
<p>再编写一个AndoridSaxXml(测试类中使用到的)类:</p>
<p><strong>package</strong> com.changcheng.androidxml.xml;</p>
<p><strong>import</strong> java.io.InputStream;</p>
<p><strong>import</strong> java.util.List;</p>
<p><strong>import</strong> javax.xml.parsers.SAXParser;</p>
<p><strong>import</strong> javax.xml.parsers.SAXParserFactory;</p>
<p><strong>import</strong> com.changcheng.androidxml.entity.Book;</p>
<p><strong>public</strong> <strong>class</strong> AndoridSaxXml {</p>
<p><strong>public</strong> <strong>static</strong> List readXML(InputStream inputStream) <strong>throws</strong> Exception {</p>
<p>// 创建<span style="text-decoration: underline;">Sax</span>解析</p>
<p>SAXParserFactory saxParFac = SAXParserFactory.<em>newInstance</em>();</p>
<p>SAXParser saxParser = saxParFac.newSAXParser();</p>
<p>SaxXmlContentHandler handler = <strong>new</strong> SaxXmlContentHandler();</p>
<p>// 解析XML文件</p>
<p>saxParser.parse(inputStream, handler);</p>
<p>inputStream.close();</p>
<p><strong>return</strong> handler.getBooks();</p>
<p>}</p>
<p>}</p>
<p><strong>6.</strong><strong>运行测试</strong></p>
<p>在outline面板中的testAndroidSaxReadXML方法或在TestAndroidXML类的testAndroidSaxReadXML方法上右键->Debug As->Android Junit Test。运行结束后在LogCat面板中查看运行结束。</p>
<p>关于使用Sax生成XML文档,我在此就不做总结了。下面的Pull技术才是我们进行Android开发的重点。</p>
<p><strong>二、Pull解析技术</strong></p>
<p>Pull解析技术与Sax解析技术原理相同,但比Sax解析简单,它们的解析速度和占用的资源差不多。Android内部使用的XML解析技术正是Pull,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。下面我们使用Pull解析技术解析XML文件,然后再使用Pull技术生成XML文件。</p>
<p><strong>Pull</strong><strong>解析XML文档</strong></p>
<p><strong>1.XML</strong><strong>文件</strong></p>
<p>依然使用上面的books.xml</p>
<p><strong>2.XML</strong><strong>文档对应的实体Book</strong></p>
<p>依然使用上面的Book.java</p>
<p><strong>3.Pull</strong><strong>解析XML类</strong></p>
<p><strong>package</strong> com.changcheng.androidxml.xml;</p>
<p><strong>import</strong> java.io.InputStream;</p>
<p><strong>import</strong> java.io.Writer;</p>
<p><strong>import</strong> java.util.ArrayList;</p>
<p><strong>import</strong> java.util.List;</p>
<p><strong>import</strong> org.xmlpull.v1.XmlPullParser;</p>
<p><strong>import</strong> org.xmlpull.v1.XmlPullParserFactory;</p>
<p><strong>import</strong> org.xmlpull.v1.XmlSerializer;</p>
<p><strong>import</strong> android.util.Xml;</p>
<p><strong>import</strong> com.changcheng.androidxml.entity.Book;</p>
<p><strong>public</strong> <strong>class</strong> AndroidPullXML {</p>
<p><strong>public</strong> <strong>static</strong> List readXML(InputStream inputStream,</p>
<p>String inputEncoding) <strong>throws</strong> Exception {</p>
<p>// 创建Pull解析</p>
<p>XmlPullParserFactory pullParserFactory = XmlPullParserFactory</p>
<p>.<em>newInstance</em>();</p>
<p>XmlPullParser pullParser = pullParserFactory.newPullParser();</p>
<p>// 解析XML</p>
<p>pullParser.setInput(inputStream, inputEncoding);</p>
<p>// 开始</p>
<p><strong>int</strong> eventType = pullParser.getEventType();</p>
<p>List books = <strong>null</strong>;</p>
<p>Book book = <strong>null</strong>;</p>
<p><strong>while</strong> (eventType != XmlPullParser.<em>END_DOCUMENT</em>) {</p>
<p>String nodeName = pullParser.getName();</p>
<p><strong>switch</strong> (eventType) {</p>
<p>// 文档开始</p>
<p><strong>case</strong> XmlPullParser.<em>START_DOCUMENT</em>:</p>
<p>books = <strong>new</strong> ArrayList();</p>
<p><strong>break</strong>;</p>
<p>// 节点开始</p>
<p><strong>case</strong> XmlPullParser.<em>START_TAG</em>:</p>
<p><strong>if</strong> ("book".equals(nodeName)) {</p>
<p>book = <strong>new</strong> Book();</p>
<p>book.setId(Integer</p>
<p>.<em>parseInt</em>(pullParser.getAttributeValue(0)));</p>
<p>} <strong>else</strong> <strong>if</strong> ("name".equals(nodeName)) {</p>
<p>book.setName(pullParser.nextText());</p>
<p>} <strong>else</strong> <strong>if</strong> ("price".equals(nodeName)) {</p>
<p>book.setPrice(Float.<em>parseFloat</em>(pullParser.nextText()));</p>
<p>}</p>
<p><strong>break</strong>;</p>
<p>// 节点结束</p>
<p><strong>case</strong> XmlPullParser.<em>END_TAG</em>:</p>
<p><strong>if</strong> ("book".equals(nodeName)) {</p>
<p>books.add(book);</p>
<p>book = <strong>null</strong>;</p>
<p>}</p>
<p><strong>break</strong>;</p>
<p>}</p>
<p>eventType = pullParser.next();</p>
<p>}</p>
<p><strong>return</strong> books;</p>
<p>}</p>
<p>}</p>
<p><strong>4.</strong><strong>编写测试Pull解析XML类</strong></p>
<p>在sax测试类TestAndroidXML中添加一个测试方法:</p>
<p>/**</p>
<p>* 测试Pull解析XML</p>
<p>* <strong>@throws</strong> Throwable</p>
<p>*/</p>
<p><strong>public</strong> <strong>void</strong> testAndroidPullReadXML() <strong>throws</strong> Throwable {</p>
<p>InputStream file = <strong>this</strong>.getClass().getClassLoader().getResourceAsStream("books.xml");</p>
<p><strong>try</strong> {</p>
<p>List books = AndroidPullXML.<em>readXML</em>(file, "UTF-8");</p>
<p>Log.<em>i</em>(<em>TAG</em>, books.toString());</p>
<p>} <strong>catch</strong> (Exception e) {</p>
<p>Log.<em>e</em>(<em>TAG</em>, e.toString());</p>
<p>}</p>
<p>}</p>
<p><strong>5.</strong><strong>运行测试</strong></p>
<p>在outline面板中的testAndroidPullReadXML方法或在TestAndroidXML类的testAndroidPullReadXML方法上右键->Debug As->Android Junit Test。运行结束后在LogCat面板中查看运行结束。</p>
<p><strong>Pull</strong><strong>生成XML文档</strong></p>
<p>使用Pull生成上面的books.xml文档。</p>
<p><strong>1.</strong><strong>在AndroidPullXML类中添加一个方法:</strong></p>
<p><strong>public</strong> <strong>static</strong> <strong>void</strong> writeXML(Writer writer, List books)</p>
<p><strong>throws</strong> Exception {</p>
<p>// 创建XML生成器</p>
<p>XmlSerializer writexml = Xml.<em>newSerializer</em>();</p>
<p>writexml.setOutput(writer);</p>
<p>// 生成XML文档</p>
<p>writexml.startDocument("UTF-8", <strong>true</strong>);</p>
<p>writexml.startTag("", "books");</p>
<p><strong>for</strong> (Book book : books) {</p>
<p>// name</p>
<p>writexml.startTag("", "name");</p>
<p>writexml.attribute("", "id", book.getId() + "");</p>
<p>writexml.text(book.getName());</p>
<p>writexml.endTag("", "name");</p>
<p>// price</p>
<p>writexml.startTag("", "price");</p>
<p>writexml.text(book.getPrice() + "");</p>
<p>writexml.endTag("", "price");</p>
<p>}</p>
<p>//</p>
<p>writexml.endTag("", "books");</p>
<p>}</p>
<p><strong>2.</strong><strong>编写测试Pull生成XML方法</strong></p>
<p>在sax测试类TestAndroidXML中添加一个测试方法:</p>
<p>/**</p>
<p>* 测试Pull生成XML</p>
<p>* <strong>@throws</strong> Throwable</p>
<p>*/</p>
<p><strong>public</strong> <strong>void</strong> testAndroidPullWriteXML() <strong>throws</strong> Throwable {</p>
<p>// 生成到内存中。(也可以生成到文件中,那就需要定义一个文件输出流。)</p>
<p>StringWriter writer = <strong>new</strong> StringWriter();</p>
<p>// 添加三本书</p>
<p>List books = <strong>new</strong> ArrayList();</p>
<p>books.add(<strong>new</strong> Book(1, "C", 89));</p>
<p>books.add(<strong>new</strong> Book(1, "C++", 100));</p>
<p>books.add(<strong>new</strong> Book(1, "Java", 87));</p>
<p>books.add(<strong>new</strong> Book(1, "JavaEE", 95));</p>
<p>// 生成XML</p>
<p>AndroidPullXML.<em>writeXML</em>(writer, books);</p>
<p>// 打印结果</p>
<p>Log.<em>i</em>(<em>TAG</em>, books.toString());</p>
<p>}</p>
<p><strong>3.</strong><strong>运行测试</strong></p>
<p>在outline面板中的testAndroidPullWriteXML方法或在TestAndroidXML类的testAndroidPullWriteXML方法上右键->Debug As->Android Junit Test。运行结束后在LogCat面板中查看运行结束。</p>
<p>OK,使用Sax和Pull在Android中解析XML文档到此完成。在Andorid中还可以使用DOM技术,使用DOM技术解析在我们学习JavaWeb基础时,已经做了总结,在此就不再介绍了。</p>

转载地址:http://edaji.baihongyu.com/

你可能感兴趣的文章
maven hibernate 实现对mysql简单的CRUD操作
查看>>
Java 线程池学习
查看>>
j2ee中的listener、 filter、servlet 加载顺序及其详解
查看>>
j2ee中web.xml中配置listener
查看>>
web.xml中load-on-startup的作用
查看>>
MySQL导入sql 文件的5大步骤
查看>>
释放MySQL ibdata1文件的空间
查看>>
is not in the sudoers file. This incident will be reported.
查看>>
win7 Centos 双系统的时间问题
查看>>
CentOs安装无线网卡后,一段时间后不用,网络自动断开的解决办法
查看>>
Centos 成功安装NTFS-3G
查看>>
Linux下tar.xz结尾的文件的解压方法
查看>>
yum install vlc
查看>>
Java技术路线图
查看>>
Java学习的30个目标
查看>>
Spring2.5+MINA2搭建Socket Server
查看>>
jcharts画线图,饼图和柱状图
查看>>
DOS 命令大全
查看>>
linux nc 端口转发
查看>>
less 快速入门(一)
查看>>