虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Android编程 > Android编程实现XML解析与保存的三种方法详解

Android编程实现XML解析与保存的三种方法详解
类别:Android编程   作者:码皇   来源:互联网   点击:

这篇文章主要介绍了Android编程实现XML解析与保存的三种方法,结合实例形式详细分析了Android实现xml解析的SAX、DOM、PULL三种方法的相关操作技巧,需要的朋友可以参考下

本文实例讲述了Android编程实现XML解析与保存的三种方法。分享给大家供大家参考,具体如下:

简介

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

1. SAX 基于事件的解析器,解析速度快,占用内存少。非常适合在Android移动设备中使用。
2. DOM 在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源
3. PULL 基于事件的解析器,不同于SAX是,PULL是主动请求下一个事件,所以在可控上PULL要比SAX实用。Android系统内部在解析各种XML时也是用PULL解析器。

下面实现各种解析的类以及工程结构

这是我们将要解析的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("n");
    }
    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://www.jb51.net/article/97247.htm
http://www.jb51.net/article/97376.htm

PS:这里再为大家提供几款关于xml操作的在线工具供大家参考使用:

在线XML/JSON互相转换工具:
http://tools.jb51.net/code/xmljson

在线格式化XML/在线压缩XML
http://tools.jb51.net/code/xmlformat

XML在线压缩/格式化工具:
http://tools.jb51.net/code/xml_format_compress

XML代码在线格式化美化工具:
http://tools.jb51.net/code/xmlcodeformat

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android操作XML数据技巧总结》、《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》、《Android文件操作技巧汇总》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结

希望本文所述对大家Android程序设计有所帮助。

相关热词搜索: Android XML 解析 保存