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

作者:QQxiaoqiang1573 时间:2022-04-15 00:39:01 

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

简介

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

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

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

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

这是我们将要解析的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>

效果图

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

参考文章
https://www.jb51.net/article/97247.htm
https://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程序设计有所帮助。

来源:http://blog.csdn.net/qqxiaoqiang1573/article/details/50739448

标签:Android,XML
0
投稿

猜你喜欢

  • C++如何通过ostringstream实现任意类型转string

    2022-06-27 16:23:06
  • Java多线程Thread基础学习

    2023-04-17 17:12:21
  • C# datatable 不能通过已删除的行访问该行的信息处理方法

    2022-07-31 02:57:08
  • Java继承方法重写实现原理及解析

    2021-12-31 16:35:54
  • SpringBoot整合MyCat实现读写分离的方法

    2022-03-05 23:37:45
  • 将Qt项目升级到Qt6吐血经验总结

    2023-08-22 08:08:30
  • C#编程实现四舍五入、向上及下取整的方法

    2023-10-25 07:59:38
  • C# Resources资源详解

    2021-10-13 02:49:32
  • C#如何自定义multipart/form-data的解析器

    2023-12-04 18:59:03
  • Android实现拍照、选择相册图片并裁剪功能

    2022-09-22 12:25:44
  • SpringCloud项目中Feign组件添加请求头所遇到的坑及解决

    2023-04-28 03:46:58
  • Java实现树形List与扁平List互转的示例代码

    2023-03-15 00:18:23
  • java poi sax方式处理大数据量excel文件

    2021-09-19 19:28:48
  • idea mybatis配置log4j打印sql语句的示例

    2023-11-25 10:32:39
  • C#采用FileSystemWatcher实现监视磁盘文件变更的方法

    2023-12-10 02:52:49
  • JAVA多线程之实现用户任务排队并预估排队时长

    2022-03-26 03:06:20
  • IDEA JetBrains Mono字体介绍和安装教程(详解)

    2022-01-23 17:57:51
  • Java中Map与JSON数据之间的互相转化

    2021-10-26 01:56:19
  • JavaWeb中JavaMail创建邮件和发送邮件

    2022-01-29 02:54:09
  • 浅析Java的Hibernate框架中的继承关系设计

    2021-10-18 03:10:03
  • asp之家 软件编程 m.aspxhome.com