android中的xml解析方式小結

本文參考學習了:
http://blog.csdn.net/liuhe688/article/details/6415593/
我這裏主要考慮實戰性,只學習pull方式,給出一些需要注意的地方!!!
通常Android下xml解析方式有三種:
1、sax解析
2、pull解析
3、dom解析

sax和pull都是基於事件驅動的,區別就是sax事件是系統指定的,
pull是程序員代碼啓動的。

dom是以樹狀結構進行解析,確定就是文件非常大,一下子加載在內存ram裏面,太損耗內存了,卡死。

android推薦使用pull解析,自帶解析器。所以個人認識把pull解析搞懂就可以了,當然,你有時間也可以學習其他兩種模式!!!別學我偷懶啊
demo:
在工程的根目錄下創建/assets/books.xml文件,內容:

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book
        year="2001"
        type="java技術"
    >
        <id> 1001
        </id>
        <name> Thinking In Java
        </name>
        <price> 80.00
        </price>
    </book>
    <book
        year="2002"
        type="java技術"
    >
        <id> 1002
        </id>
        <name> Core Java
        </name>
        <price> 90.00
        </price>
    </book>
    <book
        year="2003"
        type="android技術"
    >
        <id> 1003
        </id>
        <name> Hello, Andriod
        </name>
        <price> 100.00
        </price>
    </book>
    <book
        year="2004"
        type="文學"
    >
        <id>1004</id>
        <name>西遊記</name>
        <price>150.00</price>
    </book>
    <book
        year="2005"
        type="禁書"
    >
        <id> 1005
        </id>
        <name> 金瓶梅
        </name>
        <price> 200.00
        </price>
    </book>
</books>

對這個xml文件進行解析,之後再把解析出來的內容寫到
data/data/應用包名/files/book2.xml中
對這個xml進行分析,抽象出一個
book.java

package com.example.pull_dom_parser;

public class Book {
    /*
     * <id> 1001 </id> <name> Thinking In Java </name> <price> 80.00 </price>
     */
    private String yearString, type, id, name, price;

    public Book() {
        super();
    }

    public Book(String yearString, String type, String id, String name,
            String price) {
        super();
        this.yearString = yearString;
        this.type = type;
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public String getYearString() {
        return yearString;
    }

    public void setYearString(String yearString) {
        this.yearString = yearString;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book [yearString=" + yearString + ", type=" + type + ", id="
                + id + ", name=" + name + ", price=" + price + "]";
    }

}

爲了實現pull\dom\sax三種模式的擴展,可以定義接口
BookParser.java:

/**
 * 
 */
package com.example.pull_dom_parser;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * @author lihui20
 * 
 */
public interface BookParser {
    // 讀取
    public List<Book> readFromXML(InputStream inputStream);

    // 寫入
    String writeToXML(List<Book> list);

}

後面可以根據不同的方式實現這個接口,重寫接口方法。

這裏我使用pull方式:
PullBookParse .java

package com.example.pull_dom_parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Log;
import android.util.Xml;

public class PullBookParse implements BookParser {

    @Override
    public List<Book> readFromXML(InputStream inputStream) {
        // TODO Auto-generated method stub
        XmlPullParser xmlPullParser = Xml.newPullParser();
        List<Book> books = null;
        Book book = null;
        try {
            xmlPullParser.setInput(inputStream, "UTF-8");
            int eventType = xmlPullParser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    // 一次
                    books = new ArrayList<Book>();
                    break;
                case XmlPullParser.START_TAG:
                    if (xmlPullParser.getName().equals("book")) {
                        book = new Book();
                        // year type
                        book.setYearString(xmlPullParser.getAttributeValue(0));
                        book.setType(xmlPullParser.getAttributeValue(1));

                    } else if (xmlPullParser.getName().equals("id")) {
                        book.setId(xmlPullParser.nextText());
                    } else if (xmlPullParser.getName().equals("name")) {
                        book.setName(xmlPullParser.nextText());
                    } else if (xmlPullParser.getName().equals("price")) {
                        book.setPrice(xmlPullParser.nextText());
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (xmlPullParser.getName().equals("book")) {
                        books.add(book);
                    }
                    break;
                case XmlPullParser.END_DOCUMENT:

                    break;
                default:
                    break;
                }

                // next下一個事件
                eventType = xmlPullParser.next();

            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return books;
    }

    @Override
    public String writeToXML(List<Book> list) {
        // TODO Auto-generated method stub
        // 能讀取,就可以寫到xml裏面
        // 定義頭標籤
        XmlSerializer xmlSerializer = Xml.newSerializer();
        StringWriter stringWriter = new StringWriter();
        String namespace = "";
        try {
            xmlSerializer.setOutput(stringWriter);
            xmlSerializer.startDocument("UTF-8", true);

            xmlSerializer.startTag(namespace, "books");
            for (Book book : list) {
                xmlSerializer.startTag(namespace, "book");
                xmlSerializer
                        .attribute(namespace, "year", book.getYearString());
                xmlSerializer.attribute(namespace, "type", book.getType());

                //
                xmlSerializer.startTag(namespace, "id");
                xmlSerializer.text(book.getId());
                xmlSerializer.endTag(namespace, "id");
                //
                xmlSerializer.startTag(namespace, "name");
                xmlSerializer.text(book.getName());
                xmlSerializer.endTag(namespace, "name");
                //
                xmlSerializer.startTag(namespace, "price");
                xmlSerializer.text(book.getPrice());
                xmlSerializer.endTag(namespace, "price");
                //
                xmlSerializer.endTag(namespace, "book");

            }

            xmlSerializer.endTag("", "books");
            xmlSerializer.endDocument();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Log.d("test1448",
                "stringWriter.toString()---" + stringWriter.toString());
        // 開始寫xml,標籤、內容
        return stringWriter.toString();
    }

}

註解:
這裏用到了stringbuffer,這個流不是把內容寫到文件、xml、txt、數據庫等裏面的,是把文字寫到RAM內存裏的,臨時存放。用於後續輸出到book2.xml中。

pull解析主要是事件驅動
int eventType = xmlPullParser.getEventType();
事件類型:
1、解析文檔開始事件
2、遇到開始標籤事件

<xxxx>

3、遇到結束事件

</xxxx>

4、解析文檔結束事件

文本類型
文本類型2個:
1、標籤文本

<xxx></xxx>

這裏的xxx就是標籤文本
2、text內容文本
就是除了標籤文本外出現的文字

hello<xxx>12312213</xxx>world

hello
12312213
world
這些是text文本

好了,工具寫好了。
在activity中調用吧。

package com.example.pull_dom_parser;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
    Button readButton, writeButton;
    TextView showText;
    Context mContext;
    private List<Book> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        initView();
    }

    private void initView() {
        // TODO Auto-generated method stub
        readButton = (Button) findViewById(R.id.button1);
        writeButton = (Button) findViewById(R.id.button2);
        showText = (TextView) findViewById(R.id.textView1);
        readButton.setOnClickListener(this);
        writeButton.setOnClickListener(this);

    }

    @SuppressWarnings("resource")
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.button1:

            PullBookParse pullBookParse = new PullBookParse();
            AssetManager assetManager = getResources().getAssets();
            InputStream inputStream = null;
            try {
                inputStream = assetManager.open("books.xml");
                list = pullBookParse.readFromXML(inputStream);
                StringBuffer stringBuffer = new StringBuffer();
                for (Book book : list) {
                    stringBuffer.append(book.toString() + "\r\n");
                }
                showText.setText("從xml中讀取內容:\r\n" + stringBuffer.toString());

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }
            break;
        case R.id.button2:
            // data/data/包名 下生成一個文件,把讀取的內容寫進去
            PullBookParse bookParser = new PullBookParse();
            File xmlFile = new File(getFilesDir().getAbsoluteFile(),
                    "books2.xml");
            String xmlString = bookParser.writeToXML(list);
            Log.d("xmlString", "xmlString---" + xmlString);
            // OutputStream out = null;
            try {
                // out = new FileOutputStream(xmlFile);
                FileOutputStream out = this.openFileOutput("books3.xml",
                        MODE_PRIVATE);
                BufferedWriter bufferedWriter = new BufferedWriter(
                        new OutputStreamWriter(out));
                bufferedWriter.write(xmlString);
                bufferedWriter.flush();
                out.close();
                bufferedWriter.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            break;
        case R.id.textView1:

            break;
        default:
            break;
        }
    }

}

layout.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.pull_dom_parser.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="讀取xml" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button1"
        android:layout_alignBottom="@+id/button1"
        android:layout_toRightOf="@+id/button1"
        android:text="寫入xml" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button1"
        android:text="TextView" />

</RelativeLayout>

註解:
在每個目錄下,一般有這麼幾個子目錄經常使用到:

databases : 存放數據庫

cache : 存放緩存數據

files : 存放應用程序自己控制的文件

lib : 存放使用的包
每個應用程序的代碼,對自己的目錄是有絕對的控制權限的。

我們使用了files目錄。
獲取可以使用:
FileOutputStream out = this.openFileOutput(“books3.xml”,
MODE_PRIVATE);
或者:
File xmlFile = new File(getFilesDir().getAbsoluteFile(),
“books2.xml”);

當用輸出流bufferwriter需要
bufferedWriter.flush();之後,
out.close();
bufferedWriter.close();
否則無法寫到文件中。
必須flush刷新一下!!!!

好了,android pull解析讀取xml、寫入xml,就這樣吧~~~~

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