解析XML:DOM,SAX,PULL

Android解析XML有三種方式:DOM(document object model)、SAX(simple api XML)、PULL

1、DOM

  DOM解析XML文件時,會將XML文件的所有內容讀取到內存中,然後允許您使用DOM API遍歷XML樹、檢索所需的數據。使用DOM操作XML的代碼看起來比較直觀,並且,在某些方面比基於SAX的實現更加簡單。但是,因爲DOM需要將 XML文件的所有內容讀取到內存中,所以內存的消耗比較大,特別對於運行Android的移動設備來說,因爲設備的資源比較寶貴,所以建議還是採用SAX 來解析XML文件,當然,如果XML文件的內容比較小採用DOM是可行的。

2、SAX

  SAX是一個解析速度快並且佔用內存少的xml解析器,非常適合用於Android等移動設備。?SAX解析XML文件採用的是事件驅動,也就是說,它並不需要解析完整個文檔,在按內容順序解析文檔的過程中,SAX會判斷當前讀到的字符是否合法XML語法中的某部分,如果符合就會觸發事件。所謂事件,其實就是一些回調(callback)方法,這些方法(事件)定義在ContentHandler接口。

  這種方式解析是一種基於事件驅動的api,有兩個部分,解析器和事件處理器:

  • 解析器就是XMLReader接口,負責讀取XML文檔,和向事件處理器發送事件(也是事件源),
  • 事件處理器ContentHandler接口,負責對發送的事件響應和進行XML文檔處理。

3、PULL

  Pull解析器的運行方式與 SAX 解析器相似,都是輕量級的解析,在Android的內核中已經嵌入了Pull,所以我們不需要再添加第三方jar包來支持Pull。

  Pull解析和Sax解析不一樣的地方有

  1. pull讀取xml文件後觸發相應的事件調用方法返回的是數字
  2. pull可以在程序中控制想解析到哪裏就可以停止解析。

DOME-smsBackup

    public void click(View view) {
        // TODO Auto-generated method stub
        List<SmsInfo> smsInfos = new ArrayList<SmsInfo>();
        Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"),
                new String[] { "address", "body", "date", "type" }, null, null,
                null);
        while (cursor.moveToNext()) {
            String address = cursor.getString(0);
            String body = cursor.getString(1);
            long date = cursor.getLong(2);
            int type = cursor.getInt(3);
            SmsInfo smsInfo = new SmsInfo(address, body, date, type);
            smsInfos.add(smsInfo);
        }
        SmsUtils.smsBackupXml(smsInfos, getApplicationContext());
        cursor.close();
    }

     public static void smsBackupXml(List<SmsInfo> smsInfos, Context context) {
        try {
            FileOutputStream fos = new FileOutputStream(new File(
                    Environment.getExternalStorageDirectory(), "smsBackup.xml"));
            XmlSerializer xSerializer = Xml.newSerializer();
            xSerializer.setOutput(fos, "utf-8");

            xSerializer.startDocument("utf-8", true);
            xSerializer.startTag(null, "smss");
            for (SmsInfo smsInfo : smsInfos) {
                xSerializer.startTag(null, "sms");
                xSerializer.attribute(null, "id", smsInfo.getId() + "");

                xSerializer.startTag(null, "address");
                xSerializer.text(smsInfo.getAddress());
                xSerializer.endTag(null, "address");

                xSerializer.startTag(null, "body");
                xSerializer.text(smsInfo.getBody());
                xSerializer.endTag(null, "body");

                xSerializer.startTag(null, "date");
                xSerializer.text(smsInfo.getDate() + "");
                xSerializer.endTag(null, "date");

                xSerializer.startTag(null, "type");
                xSerializer.text(smsInfo.getType() + "");
                xSerializer.endTag(null, "type");

                xSerializer.endTag(null, "sms");
            }
            xSerializer.endTag(null, "smss");
            xSerializer.endDocument();

            fos.close();
            Toast.makeText(context, "備份成功", 1).show();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(context, "備份失敗", 1).show();
        }
    }

這個demo是最簡版,如果要運用到較大數據上時需添加線程,否則會因主線程阻塞導致備份失敗

http://www.android100.org/html/201409/07/63419.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章