Xml解析
来源:互联网 发布:刘强东脸盲 知乎 编辑:程序博客网 时间:2024/06/05 05:08
XML解析在Android中应用的比较多,很多时候存储数据需要使用到XML。
这里介绍四种XML解析方式,很多地方说是三种xml解析方式(除去第一种原生xml解析),但是这里的XmlResourceParser跟其他三种不知道是否重复:
1、原生XML解析:XmlResourceParser
2、SAX解析器,
3、DOM解析器,
4、PULL解析器
公共接口:
public interface BookParser { //解析输入流,得到book对象集合 public List<Book> parse(InputStream is) throws Exception; //序列化Book对象集合,得到xml形式字符串 public String serialize(List<Book> books) throws Exception;}
公共实体类:
package com.mfc.xmlutils;/** * Created by Administrator on 2017/8/11. */public class Book { private int id; private String name; private float price; public Book() { } public Book(int id, String name, float price) { this.id = id; this.name = name; this.price = 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 "Book{" + "id=" + id + ", name='" + name + '\'' + ", price=" + price + '}'; }}
一、原生XML解析:XmlResourceParser
books.xml:(这个xml存放在res的xml文件夹里):
<?xml version="1.0" encoding="utf-8"?><books> <book price="1.0" id="1001">Java</book> <book price="89.0" id="1002">Java EE</book> <book price="69.0" id="1003">Ajax</book></books>
工具类:
package com.mfc.xmlutils;import android.content.Context;import android.content.res.XmlResourceParser;import com.example.administrator.parsexml.R;import java.util.ArrayList;import java.util.List;public class XmlResourceParserUtil { private Context context; public XmlResourceParserUtil(Context context){ this.context = context; } public List<Book> getXmlResource(){ XmlResourceParser xlp = context.getResources().getXml(R.xml.books); try { List<Book> books = new ArrayList<Book>(); Book book = null; //循环,如果还没有到xml文档的结尾处 while (xlp.getEventType() != XmlResourceParser.END_DOCUMENT){ //如果遇到了开始标签 if (xlp.getEventType() == XmlResourceParser.START_TAG){ //获取标签名 String tagName = xlp.getName(); //如果遇到Book标签 if (tagName.equals("book")){ book = new Book(); //根据属性名来获取属性值 String bookPrice = xlp.getAttributeValue(0); book.setPrice(Float.parseFloat(bookPrice)); String id = xlp.getAttributeValue(1); book.setId(Integer.parseInt(id)); //获取文本节点的值 book.setName(xlp.nextText()); books.add(book); } } xlp.next(); } return books; } catch (Exception e) { e.printStackTrace(); } return null; }}
activity:
parserButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { XmlResourceParserUtil xmlResourceParserUtil = new XmlResourceParserUtil(SAXParserXmlActivity.this); List<Book> books = xmlResourceParserUtil.getXmlResource(); StringBuilder stringBuilder = new StringBuilder(); for (Book book : books) { stringBuilder.append(book.toString()); } XMLContent.setText(stringBuilder.toString()); } });
二、SAX解析器:
books.xml(这个xml存放在assets文件夹下):以下几种解析xml的方法都使用的这一个xml
<?xml version="1.0" encoding="utf-8"?><books> <book> <id>1001</id> <name>java编程思想</name> <price>80.00</price> </book> <book> <id>1002</id> <name>Android群英传</name> <price>90.00</price> </book> <book> <id>1003</id> <name>spring源码解析</name> <price>100.00</price> </book></books>
工具类:
package com.mfc.xmlutils;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.AttributesImpl;import org.xml.sax.helpers.DefaultHandler;import java.io.InputStream;import java.io.StringWriter;import java.util.ArrayList;import java.util.List;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.TransformerFactory;import javax.xml.transform.sax.SAXTransformerFactory;import javax.xml.transform.sax.TransformerHandler;import javax.xml.transform.stream.StreamResult;/** * Created by Administrator on 2017/8/11. */public class BookSaxParser implements BookParser { @Override public List<Book> parse(InputStream is) throws Exception { //取得SAXParserFactory实例 SAXParserFactory factory = SAXParserFactory.newInstance(); //从factory获取SAXParser实例 SAXParser parser = factory.newSAXParser(); //实例化自定义的Handler MyHandler myHandler = new MyHandler(); parser.parse(is,myHandler); return myHandler.getBooks(); } @Override public String serialize(List<Book> books) throws Exception { //取得SAXTransformerFactory实例 SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance(); //从factory获取TransformerHandler实例 TransformerHandler handler = factory.newTransformerHandler(); //从handler获取Transformer实例 Transformer transformer = handler.getTransformer(); //设置输出采用的编码方式 transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); //是否自动添加额外的空白 transformer.setOutputProperty(OutputKeys.INDENT,"yes"); //是否忽略xml声明 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"no"); StringWriter writer = new StringWriter(); Result result = new StreamResult(writer); handler.setResult(result); //代表命名空间的URI,当URI无值时,需设置为空字符串 String uri = ""; //命名空间的本地名称(不包含前缀),当没有进行命名空间处理时,需要设置为空字符串 String localName = ""; handler.startDocument();; handler.startElement(uri,localName,"books",null); //负责存放元素的属性信息 AttributesImpl attrs = new AttributesImpl(); char[] ch = null; for (Book book : books){ //清空属性列表 attrs.clear(); //添加一个名为id的属性(type影响不大,这里设置为String) attrs.addAttribute(uri,localName,"id","string",String.valueOf(book.getId())); //开始一个book元素,关联上面设定的id属性 handler.startElement(uri,localName,"book",attrs); //开始一个那么属性,没有元素 handler.startElement(uri,localName,"name",null); ch = String.valueOf(book.getName()).toCharArray(); //设置price元素的文本节点 handler.characters(ch,0,ch.length); handler.endElement(uri,localName,"price"); handler.endElement(uri,localName,"book"); } handler.endElement(uri,localName,"books"); handler.endDocument(); return writer.toString(); } //需要重写DefaultHandler的方法 private class MyHandler extends DefaultHandler{ private List<Book> books; private Book book; private StringBuilder builder; //返回解析后得到的Book对象集合 public List<Book> getBooks() { return books; } //初始化 @Override public void startDocument() throws SAXException { super.startDocument(); books = new ArrayList<Book>(); builder = new StringBuilder(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); //开始如果遇到了book标签,就新建一个Book对象 if (localName.equals("book")) { book = new Book(); } //将字符长度设置为0,一边重新开始读取元素的字符节点 builder.setLength(0); } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); //将读取的字符数组追加到builder中 builder.append(ch,start,length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); //遇到book标签后,接下来将遇到的标签对应的值放进实体类对应的属性里面 if (localName.equals("id")){ book.setId(Integer.parseInt(builder.toString())); }else if (localName.equals("name")) { book.setName(builder.toString()); }else if (localName.equals("price")) { book.setPrice(Float.parseFloat(builder.toString())); }else if (localName.equals("book")) { books.add(book); } } }}
activity:
parserXmlBySAXButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { InputStream is = getAssets().open("books.xml"); //创建SaxBookParser实例 parserSAX = new BookSaxParser(); //解析输入流 books = parserSAX.parse(is); StringBuilder stringBuilder = new StringBuilder(); for (Book book : books) { stringBuilder.append(book.toString()); } XMLContent.setText(stringBuilder.toString()); } catch (Exception e) { e.printStackTrace(); } } }); writerXmlBySAXButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String xml = parserSAX.serialize(books); FileOutputStream fos = openFileOutput("books.xml", Context.MODE_PRIVATE); fos.write(xml.getBytes("UTF-8")); Toast.makeText(SAXParserXmlActivity.this, "写入成功",Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); } } });
三、DOM解析器:
工具类:
package com.mfc.xmlutils;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import java.io.InputStream;import java.io.StringWriter;import java.util.ArrayList;import java.util.List;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.OutputKeys;import javax.xml.transform.Result;import javax.xml.transform.Source;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;/** * Created by Administrator on 2017/8/12. */public class BookDomParser implements BookParser { @Override public List<Book> parse(InputStream is) throws Exception { List<Book> books = new ArrayList<Book>(); //获取DocumentBuilderFactory实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //从factory获取DocumentBuilder实例 DocumentBuilder builder = factory.newDocumentBuilder(); //解析输入流,得到Document实例 Document doc = builder.parse(is); Element rootElement = doc.getDocumentElement(); NodeList items = rootElement.getElementsByTagName("book"); for (int i=0;i<items.getLength();i++) { Book book = new Book(); Node item = items.item(i); NodeList properties = item.getChildNodes(); for (int j = 0;j<properties.getLength();j++) { Node property = properties.item(j); String nodeName = property.getNodeName(); if(nodeName.equals("id")){ book.setId(Integer.parseInt(property.getFirstChild().getNodeValue())); } else if (nodeName.equals("name")) { book.setName(property.getFirstChild().getNodeValue()); } else if (nodeName.equals("price")) { book.setPrice(Float.parseFloat(property.getFirstChild().getNodeValue())); } } books.add(book); } return books; } @Override public String serialize(List<Book> books) throws Exception { //获取DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); //由builder创建新文档 Document doc = builder.newDocument(); Element rootElement = doc.createElement("books"); for (Book book : books) { Element bookElement = doc.createElement("book"); bookElement.setAttribute("id",book.getId()+""); Element nameElement = doc.createElement("name"); nameElement.setTextContent(book.getName()); bookElement.appendChild(nameElement); Element priceElement = doc.createElement("price"); priceElement.setTextContent(book.getPrice()+""); bookElement.appendChild(priceElement); rootElement.appendChild(bookElement); } doc.appendChild(rootElement); //取得TransformerFactory实例 TransformerFactory transFactory = TransformerFactory.newInstance(); //从transFactory获取Transformer实例 Transformer transformer = transFactory.newTransformer(); //设置输出采用的编码方式 transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); //设置自动添加额外的空白 transformer.setOutputProperty(OutputKeys.INDENT,"yes"); //设置忽略xml声明 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"no"); StringWriter writer = new StringWriter(); //表明文档来源是doc Source source = new DOMSource(doc); //表明目标结果为writer Result result = new StreamResult(writer); //开始转换 transformer.transform(source,result); return writer.toString(); }}
activity:
parserXmlByDOMButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { InputStream is = getAssets().open("books.xml"); //创建SaxBookParser实例 parserDOM = new BookDomParser(); //解析输入流 books = parserDOM.parse(is); StringBuilder stringBuilder = new StringBuilder(); for (Book book : books) { stringBuilder.append(book.toString()); } XMLContent.setText(stringBuilder.toString()); } catch (Exception e) { e.printStackTrace(); } } }); writerXmlByDOMButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String xml = parserDOM.serialize(books); FileOutputStream fos = openFileOutput("books.xml", Context.MODE_PRIVATE); fos.write(xml.getBytes("UTF-8")); Toast.makeText(SAXParserXmlActivity.this, "写入成功",Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); } } });
四、PULL解析器
工具类:package com.mfc.xmlutils;import android.util.Xml;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlSerializer;import java.io.InputStream;import java.io.StringWriter;import java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2017/8/12. */public class BookPullParser implements BookParser { @Override public List<Book> parse(InputStream is) throws Exception { List<Book> books = null; Book book = null; //从android.util.Xml创建一个XmlPullParser实例 XmlPullParser parser = Xml.newPullParser(); //设置输入流,并指明编码方式 parser.setInput(is,"UTF-8"); int eventType = parser.getEventType(); while(eventType != XmlPullParser.END_DOCUMENT){ switch (eventType){ case XmlPullParser.START_DOCUMENT: books = new ArrayList<Book>(); break; case XmlPullParser.START_TAG: if (parser.getName().equals("book")) { book = new Book(); }else if (parser.getName().equals("id")){ eventType = parser.next(); book.setId(Integer.parseInt(parser.getText())); }else if (parser.getName().equals("name")){ eventType = parser.next(); book.setName(parser.getText()); }else if (parser.getName().equals("price")){ eventType = parser.next(); book.setPrice(Float.parseFloat(parser.getText())); } break; case XmlPullParser.END_TAG: if (parser.getName().equals("book")){ books.add(book); book = null; } break; } eventType = parser.next(); } return books; } @Override public String serialize(List<Book> books) throws Exception { //由android.util.Xml创建一个XmlSerializer实例 XmlSerializer serializer = Xml.newSerializer(); StringWriter writer = new StringWriter(); //设置输出方式为writer serializer.setOutput(writer); serializer.startDocument("UTF-8",true); serializer.startTag("","books"); for (Book book : books) { serializer.startTag("","book"); serializer.attribute("","id",book.getId()+""); serializer.startTag("","name"); serializer.text(book.getName()); serializer.endTag("","name"); serializer.startTag("", "price"); serializer.text(book.getPrice() + ""); serializer.endTag("", "price"); serializer.endTag("", "book"); } serializer.endTag("", "books"); serializer.endDocument(); return writer.toString(); }}
activity:
parserXmlByPULLButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { InputStream is = getAssets().open("books.xml"); //创建SaxBookParser实例 parserPULL = new BookDomParser(); //解析输入流 books = parserPULL.parse(is); StringBuilder stringBuilder = new StringBuilder(); for (Book book : books) { stringBuilder.append(book.toString()); } XMLContent.setText(stringBuilder.toString()); } catch (Exception e) { e.printStackTrace(); } } }); writerXmlByPULLButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String xml = parserPULL.serialize(books); FileOutputStream fos = openFileOutput("books.xml", Context.MODE_PRIVATE); fos.write(xml.getBytes("UTF-8")); Toast.makeText(SAXParserXmlActivity.this, "写入成功",Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); } } });
效果图(这里由于使用的真机,所以看不到写入的文件):
对于这几种解析器各有优点,更倾向于PULL解析器,因为SAX解析器操作起来太笨重,DOM不适合文档较大,内存较小的场景,唯有PULL轻巧灵活,速度快,占用内存小,使用非常顺手。
源码下载:http://download.csdn.net/download/fancheng614/9931088
阅读全文
0 0
- XML解析
- xml解析
- XML解析
- 解析XML
- xml解析
- 解析xml
- 解析xml
- xml解析
- XML解析
- xml解析
- XML解析
- xml解析
- xml解析
- xml解析
- xml解析
- xml解析
- 解析xml
- XML解析
- C语言读写文件
- Linux文件系统
- IOS RUNLOOP 深入分析
- JDBC的增、查、改、删
- 【C/C++】string和stringstream
- Xml解析
- H5面试题---&&的使用
- JSP语法
- 集训8.12
- 结构体
- 读书笔记:利用Python进行数据分析【第四章:NumPy基础-array数组】
- MQL4 语言入门。简介
- 2017 Multi-University Training Contest
- 前端性能优化--图片懒加载(lazyload image)