本文实例讲述了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程序设计有所帮助。