首页 > 系统 > Android > 正文

Android编程实现XML解析与保存的三种方法详解

2019-12-12 02:10:14
字体:
来源:转载
供稿:网友

本文实例讲述了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>

效果图

参考文章
//www.VeVB.COm/article/97247.htm
//www.VeVB.COm/article/97376.htm

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

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

在线格式化XML/在线压缩XML
http://tools.VeVB.COm/code/xmlformat

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

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

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表