• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • android SAX解析XML

    SAX(Simple API for XML)是一個解析速度快并且占用內存少的xml解析器,非常適合用于Android等移動設備。 SAX解析XML文件采用的是事件驅動,順序讀取XML文件,邊加載邊解析。也就是說,它并不需要解析完整個文檔,在按內容順序解析文檔的過程中,SAX會判斷當前讀到的字符是否合法XML語法中的某部分,如果符合就會觸發事件。(如:當遇到像文件開頭,文檔結束,或者標簽開頭與標簽結束時,會觸發一個事件,用戶通過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問,且是只讀的.)所謂事件,其實就是一些回調(callback)方法,這些方法(事件)定義在ContentHandler接口。在SAX接口中,事件源是org.xml.sax包總的XMLReader,它通過parser()方法來解析XML文檔,并產生事件。事件處理器是org.xml.sax包中的ContentHandler,DTDHandler,ErrorHandler,以及EntityResolver這4個接口。它們分別處理事件源在解析XML文檔過程中產生的不同種類的事件。


    定義的事件處理類在實現該接口時,必須實現4個接口中的所有方法。在開發中不必直接從這4個接口直接繼承,因為org.xml.sax.helper包提供了類DefaultHandler,其繼承了這4個接口,在實際開發中直接從DefaultHandler繼承并實現相關函數就可以了并調用相應的監聽器設置方法(setXXXX()來完成與XMLReader事件源的連接),為了減少工作量,SDK提供了DefaultHandler類(適配器類)來做事件處理,主要的事件的回調方法如下:

    方法 含義
    setDocumentLocator(Locator locator) 設置一個可以定位文檔位置的對象
    startDocument() 用于處理文檔解析開始事件
    startElement(String uri,String localName,String qName,Attrubutes) 處理元素開始事件,從參數中可以獲取元素所在的RUL,元素名稱,屬性列表等信息
    charachters(char[] ch,int start,int length) 處理元素的字符內容,從參數中可以獲得內容
    endElement(String uri,String localName,String qName) 處理元素結束事件,參數中可以獲得元素所在URL,元素名稱等
    endDocument() 用于處理文檔解析的結束事件

    各方法詳細說明:

    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)就可以獲取內容。




    通過XMLReader及DefaultHandler的配合來解析XML,基本思路如下:

    創建SAXParserFactory對象:SAXParserFactory factory = SAXParserFactory.newInstance();

    創建SAX解析器:SAXParser parser = factory.newSAXParser();

    實例化一個DefaultHandler對象

    將XML解析處理器(DefaultHandler對象)分配給解析器

    對文檔進行解析,將每個事件發送給處理器,parser.parse(file, contentHandler);

    通過DefaultHandler返回需要的數據集合


    具體代碼如下:

    domain:

    package cn.itcast.domain;
    
    public class Person {
        private Integer id;
        private String name;
        private Short age;
        
        public Person(){}
        
        public Person(Integer id, String name, Short age) {
            this.id = id;
            this.name = name;
            this.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 Short getAge() {
            return age;
        }
        public void setAge(Short age) {
            this.age = age;
        }
        @Override
        public String toString() {
            return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";
        }
        
    }

    service:

    package cn.itcast.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 cn.itcast.domain.Person;
    /**
     * 采用SAX解析XML內容
     */
    public class SAXPersonService {
        
        public List<Person> getPersons(InputStream inStream) throws Throwable{
            //得到一個Sax解析器工廠
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //得到解析器
            SAXParser parser = factory.newSAXParser();
            //new出一個PersonParser對象出來。把這個對象傳到下面語句中
            PersonParser personParser = new PersonParser();
            //對得到的輸入流Sax進行解析,第一個參數是要進行解析的xml內容,第二個參數是給 SAX DefaultHandler使用(回調函數)
            parser.parse(inStream, personParser);
            inStream.close();
            //返回得到的getPersons
            return personParser.getPersons();
        }
    
        private final class PersonParser extends DefaultHandler{
            //把解析到的數據都放到集合里面去
            private List<Person> persons = null;
            //記錄當前所解析到的元素節點名稱
            private String tag = null;
            private Person person = null;
            //提供一個getpersons方法,主要是為主程序使用
            public List<Person> getPersons() {
                return persons;
            }
    
            @Override
            public void startDocument() throws SAXException {
                //初始化
                persons = new ArrayList<Person>();
            }
            
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                //判斷是不是我們要解析的元素節點
                if("person".equals(localName)){
                    person = new Person();//new出person對象,把要解析的內容傳給person的Id屬性
                    person.setId(new Integer(attributes.getValue(0)));
                }
                //存放節點名稱到成員變量里面
                tag = localName;
            }
            
            @Override
            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                //首先判斷節點名稱是否為空,然后在判斷節點名稱是否為name
                if(tag!=null){
                    String data = new String(ch, start, length);//獲取文本節點的數據
                    if("name".equals(tag)){//判斷節點名稱是否為name
                        person.setName(data);//把要解析的內容傳給person的name屬性
                    }else if("age".equals(tag)){//判斷節點名稱是否為age
                        person.setAge(new Short(data));
                    }
                }
            }
    
            @Override
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
                if("person".equals(localName)){//當跟末節點為person時
                    persons.add(person);//把person放到集合persons里面
                    person = null;//把當前person設為空
                }
                //遇到結束元素就把記錄設為空
                tag = null;
            }
        }
    }

    Activity或測試類:

    public class PersonServiceTest extends AndroidTestCase {
        private static final String TAG = "PersonServiceTest";
    
        public void testSAXGetPersons() throws Throwable{
            //new出一個業務對象
            SAXPersonService service = new SAXPersonService();
            //通過類加載器加載要解析的文件
            InputStream inStream = getClass().getClassLoader().getResourceAsStream("itcast.xml");
            List<Person> persons = service.getPersons(inStream);
            for(Person person : persons){
                Log.i(TAG, person.toString());    
            }
        }
    }

    AndroidMainFest文件代碼,這里主要是用到了單元測試,需要加幾句代碼:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="cn.itcast.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=".MainActivity"
                      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-sdk android:minSdkVersion="8" />
    <instrumentation android:name="android.test.InstrumentationTestRunner"
      android:targetPackage="cn.itcast.xml" android:label="Tests for My App" />
    </manifest>


    版權聲明:本文為iteye_8785原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/iteye_8785/article/details/82574498

    智能推薦

    Android開發:XML簡介及DOM、SAX、PULL解析對比

    目錄 目錄 定義 XML(extensible Markup Language) ,是一種數據標記語言 & 傳輸格式 作用 對數據進行標記(結構化數據) 對數據進行存儲 對數據進行傳輸 與html的區別:html用于顯示信息;xml用于存儲&傳輸信息 XML特點 標簽可進行自定義 XML允許作者定義自己的標簽和文檔結構 自我描述性 XML文檔實例 僅僅是一個純文本,有文本處理能力的...

    Android使用Sax 及Pull 解析Xml demo

    客戶端開發中,越來越多的接口使用的數據傳輸類型時json了,xml相對較少。恰好當前要使用到了xml傳遞數據,寫個demo權當記錄安卓中如何使用sax 及 pull解析xml. 1.常用的幾種解析XML的方式   Dom ,Sax ,Pull  Dom解析Xml 是將整個Xm文檔當成一個對象來處理,會先把整個文檔讀入到內存里。是基于樹的結構,通常需要加載整文檔和構造DOM樹,然...

    我的Android進階之旅------>Android中解析XML 技術詳解---->SAX解析、DOM解析、PULL解析...

    XML在各種開發中都廣泛應用,Android也不例外。作為承載數據的一個重要角色,如何讀寫XML成為Android開發中一項重要的技能。今天就由我向大家介紹一下在Android平臺下幾種常見的XML解析和創建的方法。 在Android中,常見的XML解析器分別為SAX解析器、DOM解析器和PULL解析器,下面,我將一一向大家詳細介紹。 SAX解析器: SAX(Simple API for XML)...

    android解析XML文件的三方法之SAX

        采用DOM方法讀取XML文檔,由于使用DOM方法需要將整個XML文檔加載內存中,對系統資源占用比較多,這對內存比較緊張的Android系統來說,使用 DOM方法讀取XML文檔會有很大的限制。 使用SAX方法讀取XML,對內存資源的占用的比較少,因此在嵌入式設備中極力推薦使用,Android也不例外,本篇幅詳細說明Android中如何使用SAX讀取XM...

    深入分析android中用SAX解析XML文件并糾錯

    在android中解析XML文件有很多方法,今天主要介紹下SAX解析。 1、SAX簡介 SAX是基于事件驅動模型,可以捕獲到讀取文檔過程中產生的事件,比如開始文檔、結束文檔、開始元素、結束元素、文本內容事件等。通過定義一個事件處理器,在這些事件觸發后,來實現數據的獲取。通過使用XMLReader類來注冊事件處理器,在Android中有如下4個事件處理器接口,如下圖: 補充:事件驅動模型是事件源發出...

    猜你喜歡

    Xml 解析:(sax 解析)

    sax解析的原理()      解析xml有兩種技術 dom 和sax      根據xml的層級結構在內存中分配一個樹形結構      把xml中標簽,屬性,文本封裝成對象      sax方式:事件驅動,邊讀邊解析   &nb...

    XML的SAX解析

    SAX是一個順序執行,事件驅動的解析方法(事件驅動,簡單地說就是你點什么按鈕(即產生什么事件))   SAX的工作原理;           DOM解析博客地址連接:DOM解析 SAX與DOM解析的優點;SAX解析適合較大的XML文件解析,DOM可以增加節點   SAX解析的主要方法;   JAVA...

    SAX-解析XML

    基于SAX的xml解析 sax通常用來進行查找,就是搜索使用,大概流程如下 解析器工廠 解析器 XMLReader 處理器ContentHandler,這部分需要程序員自己寫 進行遍歷和指定位置查找 小結 SAX的優勢在于,找多少就加載多少,不會一下子擠滿內存,但是缺點是比較麻煩- -,處理部分 得程序員自己手寫,其實也還好.做個筆記把...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    精品国产乱码久久久久久蜜桃不卡