posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

                 今日繼續學習Android中使用PullXML解析技術實現對XML文件的解析和創建。由于明天休息,時間比較充裕,所以我也將昨天未總結的SAX解析技術在此做個總結。

           

          一、SAX解析技術

                 Sax使用的是事件驅動的流式解析技術。事件驅動的流式解析方式是,從文件的開始順序解析到文檔的結束,不可暫?;虻雇恕.斀馕龅轿臋n的開始或結束、元素的開始或結束等都會觸發一個事件,我們在事件處理方法中完成對數據的操作。由此可見,我們需要編寫實現了事件接口的類。

           

                 1.創建Android工程(eclipse3.5)

                 Project name:AndroidXML

                 BuildTarget:Android2.1

                 Application name:Android XML 解析技術

                 Package name:com.changcheng.androidxml

                 Create Activity:AndroidXML

                 Min SDK Version:7

           

                 2.需要解析的XML文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <books>

                   <book id="23">

                             <name>C++ Primer 4</name>

                             <price>78</price>

                   </book>

                   <book id="20">

                             <name>Think in Java</name>

                             <price>76</price>

                   </book>

          </books>

                 該文件存放于src源碼目錄。

           

                 3.XML文件對應的實體Book

          package com.changcheng.androidxml.entity;

           

          public class Book {

                   private int id;

                   private String name;

                   private float price;

           

                   public Book() {

                   }

           

                   public Book(int id, String name, float price) {

                             this.id = id;

                             this.name = name;

                             this.price = price;

                   }

           

                   public int getId() {

                             return id;

                   }

           

                   public void setId(int id) {

                             this.id = id;

                   }

           

                   public String getName() {

                             return name;

                   }

           

                   public void setName(String name) {

                             this.name = name;

                   }

           

                   public float getPrice() {

                             return price;

                   }

           

                   public void setPrice(float price) {

                             this.price = price;

                   }

           

                   @Override

                   public String toString() {

                             return "Book [name=" + name + ", price=" + price + "]";

                   }

          }

                

                 4.Sax解析XML的事件處理類:

                 Sax的事件處理類必須實現ContentHandler接口,但我們在這個例子中不需要使用到ContentHandler接口的所有方法,我們僅需要其中的3個方法。所以Sax為我們提供了一個沒有進行任何操作的ContentHandler實現類DefaultHandler。我們直接繼承DefaultHandler類,并重寫我們需要的方法即可。

          package com.changcheng.androidxml.xml;

           

          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.changcheng.androidxml.entity.Book;

           

          public class SaxXmlContentHandler extends DefaultHandler {

           

                   private List<Book> books;

                   private Book book;

                   private String tagName;

           

                   public List<Book> getBooks() {

                             return books;

                   }

           

                   /**

                    *      接收文檔的開始的通知。

                    */

                   @Override

                   public void startDocument() throws SAXException {

                             this.books = new ArrayList<Book>();

                   }

           

                   /**

                    *      接收字符數據的通知。

                    */

                   @Override

                   public void characters(char[] ch, int start, int length)

                                      throws SAXException {

                             if (this.tagName != null) {

                                      String data = new String(ch, start, length);

                                      if (this.tagName.equals("name")) {

                                               this.book.setName(data);

                                      } else if (this.tagName.equals("price")) {

                                               this.book.setPrice(Float.parseFloat(data));

                                      }

                             }

                   }

           

                   /**

                    *     接收元素開始的通知。

                    *  namespaceURI:元素的命名空間

                    *  localName:元素的本地名稱(不帶前綴)

                    *  qName:元素的限定名(帶前綴)

                    *     atts:元素的屬性集合

                    */

                   @Override

                   public void startElement(String uri, String localName, String qName,

                                      Attributes attributes) throws SAXException {

                             if (localName.equals("book")) {

                                      book = new Book();

                                      book.setId(Integer.parseInt(attributes.getValue(0)));

                             }

                             this.tagName = localName;

                   }

           

                   /**

                    *      接收文檔的結尾的通知。

                    *     uri:元素的命名空間

                    *     localName:元素的本地名稱(不帶前綴)

                    *     name:元素的限定名(帶前綴)

                    */

                   @Override

                   public void endElement(String uri, String localName, String qName)

                                      throws SAXException {

                             if (localName.equals("book")) {

                                      this.books.add(this.book);

                             }

                             this.tagName = null;

                   }

          }

                

                 5.編寫測試Sax解析XML的類

                 在創建工程時,生成的AndroidXML.java,并沒有被使用到。因為我們使用Android的單元測試,運行上面的程序。

           

                 編寫Android單元測試類:

          package com.changcheng.androidxml.test;

           

          import java.io.InputStream;

          import java.io.StringWriter;

          import java.util.ArrayList;

          import java.util.List;

          import com.changcheng.androidxml.entity.Book;

          import com.changcheng.androidxml.xml.AndoridSaxXml;

          import com.changcheng.androidxml.xml.AndroidPullXML;

          import android.test.AndroidTestCase;

          import android.util.Log;

           

          public class TestAndroidXML extends AndroidTestCase {

           

                   private static final String TAG = "TestAndroidXML";

                  

                   /**

                    * 測試Sax解析XML

                    * @throws Throwable

                    */

                   public void testAndroidSaxReadXML() throws Throwable{

                             InputStream file = this.getClass().getClassLoader().getResourceAsStream("books.xml");

                             try {

                                      List<Book> books = AndoridSaxXml.readXML(file);

                                      Log.i(TAG, books.toString());

                             } catch (Exception e) {

                                      Log.e(TAG, e.toString());

                             }

                   }

          }

                 測試類必須繼承自AndroidTestCase類,Android的單元測試使用的是JUnit3,所以在我們的測試方法名稱要以test開頭。

           

                 再編寫一個AndoridSaxXml(測試類中使用到的)類:

          package com.changcheng.androidxml.xml;

           

          import java.io.InputStream;

          import java.util.List;

          import javax.xml.parsers.SAXParser;

          import javax.xml.parsers.SAXParserFactory;

          import com.changcheng.androidxml.entity.Book;

           

          public class AndoridSaxXml {

                  

                   public static List<Book> readXML(InputStream inputStream) throws Exception {

                             // 創建Sax解析

                             SAXParserFactory saxParFac = SAXParserFactory.newInstance();

                             SAXParser saxParser = saxParFac.newSAXParser();

                             SaxXmlContentHandler handler = new SaxXmlContentHandler();

                             // 解析XML文件

                             saxParser.parse(inputStream, handler);

                             inputStream.close();

                             return handler.getBooks();

                   }

          }

           

                 6.運行測試

                 outline面板中的testAndroidSaxReadXML方法或在TestAndroidXML類的testAndroidSaxReadXML方法上右鍵->Debug As->Android Junit Test。運行結束后在LogCat面板中查看運行結束。

           

                 關于使用Sax生成XML文檔,我在此就不做總結了。下面的Pull技術才是我們進行Android開發的重點。

           

          二、Pull解析技術

                 Pull解析技術與Sax解析技術原理相同,但比Sax解析簡單,它們的解析速度和占用的資源差不多。Android內部使用的XML解析技術正是Pull,Android官方推薦開發者們使用Pull解析技術。Pull解析技術是第三方開發的開源技術,它同樣可以應用于JavaSE開發。下面我們使用Pull解析技術解析XML文件,然后再使用Pull技術生成XML文件。

           

          Pull解析XML文檔

                 1.XML文件

                 依然使用上面的books.xml

           

                 2.XML文檔對應的實體Book

                 依然使用上面的Book.java

                

                 3.Pull解析XML

          package com.changcheng.androidxml.xml;

           

          import java.io.InputStream;

          import java.io.Writer;

          import java.util.ArrayList;

          import java.util.List;

          import org.xmlpull.v1.XmlPullParser;

          import org.xmlpull.v1.XmlPullParserFactory;

          import org.xmlpull.v1.XmlSerializer;

          import android.util.Xml;

          import com.changcheng.androidxml.entity.Book;

           

          public class AndroidPullXML {

           

                   public static List<Book> readXML(InputStream inputStream,

                                      String inputEncoding) throws Exception {

                             // 創建Pull解析

                             XmlPullParserFactory pullParserFactory = XmlPullParserFactory

                                               .newInstance();

                             XmlPullParser pullParser = pullParserFactory.newPullParser();

                             // 解析XML

                             pullParser.setInput(inputStream, inputEncoding);

                             // 開始

                             int eventType = pullParser.getEventType();

                            

                             List<Book> books = null;

                             Book book = null;

                             while (eventType != XmlPullParser.END_DOCUMENT) {

                                      String nodeName = pullParser.getName();

                                      switch (eventType) {

                                      // 文檔開始

                                      case XmlPullParser.START_DOCUMENT:

                                               books = new ArrayList<Book>();

                                               break;

                                      // 節點開始

                                      case XmlPullParser.START_TAG:

                                               if ("book".equals(nodeName)) {

                                                         book = new Book();

                                                         book.setId(Integer

                                                                           .parseInt(pullParser.getAttributeValue(0)));

                                               } else if ("name".equals(nodeName)) {

                                                         book.setName(pullParser.nextText());

                                               } else if ("price".equals(nodeName)) {

                                                         book.setPrice(Float.parseFloat(pullParser.nextText()));

                                               }

                                               break;

                                      // 節點結束

                                      case XmlPullParser.END_TAG:

                                               if ("book".equals(nodeName)) {

                                                         books.add(book);

                                                         book = null;

                                               }

                                               break;

                                      }

                                      eventType = pullParser.next();

                             }

                             return books;

                   }

          }

           

                 4.編寫測試Pull解析XML

                 sax測試類TestAndroidXML中添加一個測試方法:

          /**

           * 測試Pull解析XML

           * @throws Throwable

           */

          public void testAndroidPullReadXML() throws Throwable {

                   InputStream file = this.getClass().getClassLoader().getResourceAsStream("books.xml");

                   try {

                             List<Book> books = AndroidPullXML.readXML(file, "UTF-8");

                             Log.i(TAG, books.toString());

                   } catch (Exception e) {

                             Log.e(TAG, e.toString());

                   }

          }

           

                 5.運行測試

                 outline面板中的testAndroidPullReadXML方法或在TestAndroidXML類的testAndroidPullReadXML方法上右鍵->Debug As->Android Junit Test。運行結束后在LogCat面板中查看運行結束。

           

          Pull生成XML文檔

                 使用Pull生成上面的books.xml文檔。

                

                 1.AndroidPullXML類中添加一個方法:

          public static void writeXML(Writer writer, List<Book> books)

                             throws Exception {

                   // 創建XML生成器

                   XmlSerializer writexml = Xml.newSerializer();

                   writexml.setOutput(writer);

                   // 生成XML文檔

                   writexml.startDocument("UTF-8", true);

                   writexml.startTag("", "books");

                   for (Book book : books) {

                             // name

                             writexml.startTag("", "name");

                             writexml.attribute("", "id", book.getId() + "");

                             writexml.text(book.getName());

                             writexml.endTag("", "name");

                             // price

                             writexml.startTag("", "price");

                             writexml.text(book.getPrice() + "");

                             writexml.endTag("", "price");

                   }

                   //

                   writexml.endTag("", "books");

          }

           

                 2.編寫測試Pull生成XML方法

                 sax測試類TestAndroidXML中添加一個測試方法:

          /**

           * 測試Pull生成XML

           * @throws Throwable

           */

          public void testAndroidPullWriteXML() throws Throwable {

                   // 生成到內存中。(也可以生成到文件中,那就需要定義一個文件輸出流。)

                   StringWriter writer = new StringWriter();

                   // 添加三本書

                   List<Book> books = new ArrayList<Book>();

                   books.add(new Book(1, "C", 89));

                   books.add(new Book(1, "C++", 100));

                   books.add(new Book(1, "Java", 87));

                   books.add(new Book(1, "JavaEE", 95));

                   // 生成XML

                   AndroidPullXML.writeXML(writer, books);

                   // 打印結果

                   Log.i(TAG, books.toString());

           

          }

           

                 3.運行測試

                 outline面板中的testAndroidPullWriteXML方法或在TestAndroidXML類的testAndroidPullWriteXML方法上右鍵->Debug As->Android Junit Test。運行結束后在LogCat面板中查看運行結束。

           

                 OK,使用SaxPullAndroid中解析XML文檔到此完成。在Andorid中還可以使用DOM技術,使用DOM技術解析在我們學習JavaWeb基礎時,已經做了總結,在此就不再介紹了。

           


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 龙江县| 图木舒克市| 玉环县| 香港| 洛南县| 比如县| 海原县| 广丰县| 滦南县| 修水县| 普格县| 澜沧| 龙游县| 建阳市| 安远县| 安福县| 颍上县| 开化县| 昌黎县| 甘谷县| 石阡县| 化州市| 确山县| 克东县| 永寿县| 淄博市| 靖宇县| 定日县| 衡阳市| 鸡东县| 合水县| 潢川县| 娱乐| 新乡县| 顺义区| 蛟河市| 商城县| 贵港市| 礼泉县| 西宁市| 望谟县|