Android中XML解析,保存的三种方法

简单介绍

在Android开发中,关于XML解析有三种方式,各自是:

  • SAX 基于事件的解析器。解析速度快。占用内存少。非常适合在Android移动设备中使用。

  • DOM 在内存中以树形结构存放,因此检索和更新效率会更高。可是对于特别大的文档,解析和载入整个文档将会非常耗资源

  • PULL 基于事件的解析器。不同于SAX是,PULL是主动请求下一个事件,所以在可控上PULL要比SAX有用。

    Android系统内部在解析各种XML时也是用PULL解析器。

以下实现各种解析的类以及project结构
这里写图片描写叙述

这是我们将要解析的XML文件id.xml以及其相应的Book

<?

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

> <books> <book id="1001"> <name>Thinking In Java</name> <price>80.0</price> </book> <book id="1002"> <name>Core Java</name> <price>90.0</price> </book> <book id="1003"> <name>Hello, Andriod</name> <price>100.0</price> </book> </books>

Book.java

public class Book {

    public static final String BOOKS = "books";
    public static final String BOOK = "book";
    public static final String ID = "id";
    public static final String NAME = "name";
    public static final String PRICE = "price";

    private int id;
    private String name;
    private float 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 "id:" + id + ",name:" + name + ",price:" + price;
    }
}

以下是XML解析类的实现

抽象类用于 XML文件读写的继承

XMLParseFactory.java

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

public abstract class XMLParseFactory {

    /**
     * 读取指定的XML文件
     * @param inputStream XML文件输入流
     */
    public abstract void readXML(InputStream inputStream);

    /**
     * 保存XML到指定的文件
     * @param filePath 文件的绝对路径
     */
    public abstract void writeXML(String filePath);

    /**
     * 获取Book对象列表
     * @return
     */
    public abstract List<Book> getBookList();

    /**
     * 设置Book对象列表
     */
    public abstract void setBookList(List<Book> bookList);
}

用SAX实现的方法

SAXParserTool.java

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserTool extends XMLParseFactory {

//  private static final String TAG = "SAXParserTool";

    private SAXHandler mHandler = new SAXHandler();

    private List<Book> mBookList;

    @Override
    public void readXML(InputStream inputStream) {

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            parser.parse(inputStream, mHandler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void writeXML(String filePath) {
        SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();
        try {
            TransformerHandler handler = factory.newTransformerHandler();
            Transformer transformer = handler.getTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");

            FileOutputStream fos = new FileOutputStream(filePath);
            OutputStreamWriter writer = new OutputStreamWriter(fos);
            Result result = new StreamResult(writer);
            handler.setResult(result);

            String uri = "";
            String localName = "";

            handler.startDocument();
            handler.startElement(uri, localName, Book.BOOKS, null);
            AttributesImpl attrs = new AttributesImpl();
            char[] ch = null;

            for (Book book:mBookList) {
                attrs.clear();
                attrs.addAttribute(uri, localName, Book.ID, "string", String.valueOf(book.getId()));
                handler.startElement(uri, localName, Book.BOOK, attrs);

                handler.startElement(uri, localName, Book.NAME, null);
                ch = book.getName().toCharArray();
                handler.characters(ch, 0, ch.length);
                handler.endElement(uri, localName, Book.NAME);

                handler.startElement(uri, localName, Book.PRICE, null);
                ch = String.valueOf(book.getPrice()).toCharArray();
                handler.characters(ch, 0, ch.length);
                handler.endElement(uri, localName, Book.PRICE);

                handler.endElement(uri, localName, Book.BOOK);
            }

            handler.endElement(uri, localName, Book.BOOKS);
            handler.endDocument();

        } catch (TransformerConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    /**
     * 获取BookList列表
     * @return
     */
    public List<Book> getBookList() { 
        if (mHandler == null) {
            return null;
        }

        return mHandler.getBookList();
    }

    /**
     * 设置BookList列表
     * @param bookList
     */
    public void setBookList(List<Book> bookList) {
        mBookList = bookList;
    }

    class SAXHandler extends DefaultHandler {

        private List<Book> mBookList;
        private Book mBook; 
        private String mTargetName;

        public List<Book> getBookList() {
            return mBookList;
        }

        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            mBookList = new ArrayList<Book>();
        }

        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            if (localName.equals(Book.BOOK)) {
                mBook = new Book();
                mBook.setId(Integer.valueOf(attributes.getValue(Book.ID)));
            } 

            mTargetName = localName;
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            super.endElement(uri, localName, qName);
            if (Book.BOOK.equals(localName)) {
                mBookList.add(mBook);
            }

            mTargetName = null;
        }

        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            super.characters(ch, start, length);
            if (Book.NAME.equals(mTargetName)) {
                mBook.setName(new String(ch, start, length));
            } else if (Book.PRICE.equals(mTargetName)) {
                mBook.setPrice(Float.valueOf(new String(ch, start, length)));
            }
        }
    }
}

用PULL实现的方法

PULLParserTool.java

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

import android.util.Xml;

public class PULLParserTool extends XMLParseFactory {

//  private static final String TAG = "PULLParserTool";
    private List<Book> mBookList;
    private Book mBook;


    @Override
    public void readXML(InputStream inputStream) {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(inputStream, "UTF-8");

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String name = parser.getName();
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    mBookList = new ArrayList<Book>();
                    break;

                case XmlPullParser.START_TAG:
//                  Log.d(TAG, "getName:"+parser.getName()+","+parser.getText());
                    if (Book.BOOK.equals(name)) {
                        mBook = new Book();
                        mBook.setId(Integer.valueOf(parser.getAttributeValue("", Book.ID)));
                    } else if (Book.NAME.equals(name)) {
                        mBook.setName(parser.nextText());
                    } else if (Book.PRICE.equals(name)) {
                        mBook.setPrice(Float.valueOf(parser.nextText()));
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (Book.BOOK.equals(name)) {
                        mBookList.add(mBook);
                    }
                    break;

                default:
                    break;
                }

                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    public void writeXML(String filePath) {
        XmlSerializer serializer = Xml.newSerializer();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filePath);
            serializer.setOutput(fos, "UTF-8");

            serializer.startDocument("UTF-8", true);
            serializer.startTag("", Book.BOOKS);

            for (Book book:mBookList) {
                serializer.startTag("", Book.BOOK);
                serializer.attribute("", Book.ID, book.getId()+"");

                serializer.startTag("", Book.NAME);
                serializer.text(book.getName());
                serializer.endTag("", Book.NAME);

                serializer.startTag("", Book.PRICE);
                serializer.text(String.valueOf(book.getPrice()));
                serializer.endTag("", Book.PRICE);

                serializer.endTag("", Book.BOOK);
            }

            serializer.endTag("", Book.BOOKS);
            serializer.endDocument();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public List<Book> getBookList() {
        return mBookList;
    }

    public void setBookList(List<Book> bookList) {
        mBookList = bookList;
    }
}

用DOM实现的方法

DOMParserTool.java

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.util.Log;

public class DOMParserTool extends XMLParseFactory {

    private static final String TAG = "DOMParserTool";
    private List<Book> mBookList;

    @Override
    public void readXML(InputStream inputStream) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document parse = builder.parse(inputStream);
            Element root = parse.getDocumentElement();
            NodeList nodeList = root.getElementsByTagName(Book.BOOK);

            mBookList = new ArrayList<Book>();
            Log.d(TAG,"length:"+nodeList.getLength());
            for (int i = 0; i < nodeList.getLength(); i++) {
                Book book = new Book();
                Element item = (Element) nodeList.item(i);
                book.setId(Integer.valueOf(item.getAttribute(Book.ID)));
                NodeList nodes = item.getChildNodes();

                for (int j = 0; j < nodes.getLength(); j++) {
                    Node node =  nodes.item(j);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        if (Book.NAME.equals(node.getNodeName())) {
                            String content = node.getTextContent();
                            book.setName(content);
                        } else if (Book.PRICE.equals(node.getNodeName())) {
                            String content = node.getTextContent();
                            book.setPrice(Float.valueOf(content));
                        }
                    }
                    Log.d(TAG, "readXML:"+node.getLocalName()+","+node.getNodeName()
                            +","+node.getNodeType()+","+node.getNodeValue()
                            +","+node.getTextContent()
                            +","+node.toString());
                }

                mBookList.add(book);
            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void writeXML(String filePath) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.newDocument();
            Element rootElement = document.createElement("books");

            for (Book book:mBookList) {
                Element bookElement = document.createElement("book");
                bookElement.setAttribute(Book.ID, book.getId()+"");

                Element nameElement = document.createElement(Book.NAME);
                nameElement.setTextContent(book.getName());
                bookElement.appendChild(nameElement);

                Element priceElement = document.createElement(Book.PRICE);
                priceElement.setTextContent(String.valueOf(book.getPrice()));
                bookElement.appendChild(priceElement);

                rootElement.appendChild(bookElement);
            }

            document.appendChild(rootElement);

            TransformerFactory transfactory = TransformerFactory.newInstance();
            Transformer transformer = transfactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");// 设置输出採用的编码方式
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");// 是否自己主动加入额外的空白
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");// 是否忽略XML声明

            FileOutputStream fos = new FileOutputStream(filePath);
            Source source = new DOMSource(document);
            Result result = new StreamResult(fos);
            transformer.transform(source, result);

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    public List<Book> getBookList() {
        return mBookList;
    }

    public void setBookList(List<Book> bookList) {
        mBookList = bookList;
    }

}

这是调用各种解析类的实现

MainActivity.java


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

import com.example.xmlparsedemo.xmlparser.Book;
import com.example.xmlparsedemo.xmlparser.DOMParserTool;
import com.example.xmlparsedemo.xmlparser.PULLParserTool;
import com.example.xmlparsedemo.xmlparser.SAXParserTool;
import com.example.xmlparsedemo.xmlparser.XMLParseFactory;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    private TextView mText;
    private XMLParseFactory parseFactory;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        init();
    }

    private void init() {
        Button saxReadBtn = (Button) findViewById(R.id.id_saxread);
        Button saxWriteBtn = (Button) findViewById(R.id.id_saxwrite);
        Button domReadBtn = (Button) findViewById(R.id.id_domread);
        Button domWriteBtn = (Button) findViewById(R.id.id_domwrite);
        Button pullReadBtn = (Button) findViewById(R.id.id_pullread);
        Button pullWriteBtn = (Button) findViewById(R.id.id_pullwrite);
        mText = (TextView) findViewById(R.id.id_text);

        saxReadBtn.setOnClickListener(this);
        saxWriteBtn.setOnClickListener(this);
        domReadBtn.setOnClickListener(this);
        domWriteBtn.setOnClickListener(this);
        pullReadBtn.setOnClickListener(this);
        pullWriteBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        InputStream inputStream;
        try {
            inputStream = getAssets().open("id.xml");

            switch (v.getId()) {
            case R.id.id_saxread:
                parseFactory = new SAXParserTool();
                parseFactory.readXML(inputStream);
                showBookList(parseFactory.getBookList());
                break;
            case R.id.id_saxwrite:
                parseFactory.setBookList(parseFactory.getBookList());
                parseFactory.writeXML(Environment.getExternalStorageDirectory().getPath()+"/id.xml");
                break;
            case R.id.id_domread:
                parseFactory = new DOMParserTool();
                parseFactory.readXML(inputStream);
                showBookList(parseFactory.getBookList());
                break;
            case R.id.id_domwrite:
                parseFactory.writeXML(Environment.getExternalStorageDirectory().getPath()+"/id2.xml");
                break;
            case R.id.id_pullread:
                parseFactory = new PULLParserTool();
                parseFactory.readXML(inputStream);
                showBookList(parseFactory.getBookList());
                break;
            case R.id.id_pullwrite:
                parseFactory.writeXML(Environment.getExternalStorageDirectory().getPath()+"/id3.xml");
                break;

            default:
                break;
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }

    }

    private void showBookList(List<Book> bookList) {
        StringBuilder builder = new StringBuilder();
        for (Book book:bookList) {
            builder.append(book.toString());
            builder.append("
");
        }

        mText.setText(builder.toString());
    }
}

解析实现的主布局
activity_main.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <Button
            android:id="@+id/id_saxread"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="SAXParserRead" />

        <Button
            android:id="@+id/id_saxwrite"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="SAXParserWrite" />

        <Button
            android:id="@+id/id_domread"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="DOMParserRead" />

        <Button
            android:id="@+id/id_domwrite"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="DOMParserWrite" />

        <Button
            android:id="@+id/id_pullread"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="PULLParserRead" />

        <Button
            android:id="@+id/id_pullwrite"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="PULLParserWrite" />

        <TextView
            android:id="@+id/id_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</ScrollView>

效果图

这里写图片描写叙述

參考文章

http://blog.csdn.net/liuhe688/article/details/6415593
http://www.cnblogs.com/devinzhang/archive/2012/01/16/2323668.html
http://www.cnblogs.com/weixing/archive/2013/08/07/3243366.html

原文地址:https://www.cnblogs.com/claireyuancy/p/7055855.html