Dom、Sax、Pull解析xml文件
2016-06-22 21:18
537 查看
使用以上三种方式解析xml文件
在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX、Pull、Dom解析方式。DOM,它的特点是一次全部加载,如果对于数据量小的情况下,它的效率还可以,如果XML文件很大的情况下,速度就会慢起来。
SAX,方式比较符合我们日常思维方式,容易上手,但是它直接把文档调入内存中,比较耗内存。
PULL,用法大致和sax一样,但它可以在程序中控制,想解析到哪里就可以停止到哪里,Android中更推荐使用pull解析。
接下来举个简单的例子,使用以上三种方式解析:
<books> <book> <price>50</price> <name>三国演义</name> <author age="23">罗贯中</author> </book> <book> <price>60</price> <name>红楼梦</name> <author age="59">曹雪芹</author> </book> <book> <price>40</price> <name>水浒传</name> <author age="12">施耐庵</author> </book> </books>
将以上文件存放在assets文件夹下进行读取解析:
首先定义接口类实现方法:
package com.example.dom.parser; import java.io.InputStream; import java.util.List; import com.example.dom.beans.Book; /** * 解析接口 */ public interface IParser { /** * 解析xml文件 * * @param is * xml文件输入流 * @return book列表 */ public List<Book> parse(InputStream is); }
第一种:DOM解析:
package com.example.dom.parser; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.example.dom.beans.Book; public class DomParser implements IParser { @Override public List<Book> parse(InputStream is) { // 创建list用于保存解析出来的book List<Book> list = new ArrayList<Book>(); try { // 首先,我们创建一个工厂对象,注意:它的创建方式,不是new出来的 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 通过咱们的工厂对象,创建出DocumentBuilder DocumentBuilder docBuilder = factory.newDocumentBuilder(); // 将流转成Document对象 Document doc = docBuilder.parse(is); // 从Document对象中,获取根结点 Element rootElement = doc.getDocumentElement(); // 从根结点中获取所有的book NodeList books = rootElement.getElementsByTagName("book"); // 遍历book列表 for (int i = 0; i < books.getLength(); i++) { Book book = new Book(); //获取单个book结点 Node bookNode = books.item(i); //获取book结点下的所有子结点 NodeList childNodes = bookNode.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { //取一个子结点 Node n = childNodes.item(j); // 获取结点名称 String nodeName = n.getNodeName(); if ("name".equalsIgnoreCase(nodeName)) { // 判断是name结点时,把结点的值设置给book对象的name属性 String name = n.getFirstChild().getNodeValue(); book.setName(name); }else if("author".equalsIgnoreCase(nodeName)){ // 判断是author结点时,把结点的值设置给book对象的author属性 String author = n.getFirstChild().getNodeValue(); book.setAuthor(author); //取age属性值 NamedNodeMap attributes = n.getAttributes(); Node namedItem = attributes.getNamedItem("age"); String propertyValue = namedItem.getNodeValue(); }else if("price".equalsIgnoreCase(nodeName)){ // 判断是price结点时,把结点的值设置给book对象的price属性 String price = n.getFirstChild().getNodeValue(); book.setPrice(price); } } list.add(book); } } catch (Exception e) { e.printStackTrace(); } return list; } }
第二种SAX解析:
package com.example.dom.parser; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import com.example.dom.beans.Book; import android.util.Log; /** * <p> * Description:sax解析类,使用后置标签,即endElement方法实现 * </p> * */ public class SaxParser implements IParser { @Override public List<Book> parse(InputStream is) { // 创建list用于保存解析出来的book List<Book> list = new ArrayList<Book>(); try { // 创建SAXParserFactory对象,用于生成saxParser SAXParserFactory factory = SAXParserFactory.newInstance(); // 通过SAXParserFactory创建parser解析器 SAXParser parser = factory.newSAXParser(); // 从解析器中获取reader XMLReader reader = parser.getXMLReader(); SaxHandler handler = new SaxHandler(); reader.setContentHandler(handler); reader.parse(new InputSource(is)); return handler.getList(); } catch (Exception e) { e.printStackTrace(); } return list; } /** * <p> * Description:解析处理类 * </p> */ static class SaxHandler extends DefaultHandler { private Book book; private String value; // 用于记录文本信息 private List<Book> list;// 用于保存解析完的book对象 @Override public void startDocument() throws SAXException { // 文档开始的时候,去创建list list = new ArrayList<Book>(); book = null; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { Log.e("", "==startElement==" + qName); // 如果是book标签的开始,那么我们需要创建book对象 if ("book".equalsIgnoreCase(qName)) { book = new Book(); } if ("author".equals(qName)) { Log.e("", "==author==" + attributes.getValue("age")); } } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 为book对象设置属性值 if ("name".equals(qName)) { book.setName(value); } else if ("author".equalsIgnoreCase(qName)) { book.setAuthor(value); } else if ("price".equalsIgnoreCase(qName)) { book.setPrice(value); } else if ("book".equalsIgnoreCase(qName)) { // 如果是book标签的结束,那么将book对象添加到list中 list.add(book); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { // 获取文本信息 value = new String(ch, start, length); } public List<Book> getList() { return list; } } }
第三种 PULL解析:
package com.example.dom.parser; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import com.example.dom.beans.Book; import android.content.res.XmlResourceParser; import android.util.Log; import android.util.Xml; /** * <p>Description:</p> * */ public class PullParser implements IParser { // 创建list用于保存解析出来的book private List<Book> list = null; @Override public List<Book> parse(InputStream is) { try { XmlPullParser xmlParser = Xml.newPullParser(); xmlParser.setInput(is, "utf-8"); Book book = null; int eventType = xmlParser.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { String tagName = xmlParser.getName(); //获取当前标签 switch (eventType) { case XmlResourceParser.START_DOCUMENT: list = new ArrayList<Book>(); break; case XmlResourceParser.START_TAG: // 如果是book标签的开始,那么我们需要创建book对象 if ("book".equalsIgnoreCase(tagName)) { book = new Book(); } else if ("name".equals(tagName)) { book.setName(xmlParser.nextText()); } else if ("author".equalsIgnoreCase(tagName)) { Log.e("", "==age=" + xmlParser.getAttributeValue(null, "age")); book.setAuthor(xmlParser.nextText()); } else if ("price".equalsIgnoreCase(tagName)) { book.setPrice(xmlParser.nextText()); } break; case XmlResourceParser.END_TAG: if ("book".equalsIgnoreCase(tagName)) { Log.e("", "===" + book); list.add(book); book = null; } break; } eventType = xmlParser.next(); } } catch (Exception e) { e.printStackTrace(); } return list; } }
bean类:
package com.example.dom.beans; import java.io.Serializable; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 图书实体类 */ @XStreamAlias("book") public class Book implements Serializable { private static final long serialVersionUID = 1L; private String name;// 书名 private String author;// 作者 private String price;// 价格 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(name).append("\t").append(author).append("\t").append(price).append("元"); return sb.toString(); // return "Book [name=" + name + ", author=" + author + ", price=" + price + "]"; } }
返回时调用的bean类:
package com.example.dom.beans; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; @XStreamAlias("books") public class Books { private List<Book> book; }
MainActivity中实现:
package com.example.dom; import java.util.List; import com.example.dom.beans.Book; import com.example.dom.parser.DomParser; import com.example.dom.parser.IParser; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { private ListView mLv; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLv = (ListView) findViewById(R.id.lv); try { IParser parser = new DomParser(); // IParser parser = new SaxParser(); // IParser parser = new PullParser(); List<Book> list = parser.parse(getAssets().open("book.xml")); ArrayAdapter<Book> adapter = new ArrayAdapter<Book>(this, android.R.layout.simple_list_item_1, list); mLv.setAdapter(adapter); } catch (Exception e) { e.printStackTrace(); } } }
以上是使用三种解析方式对简单的xml进行了解析案例,希望能够帮助大家。
相关文章推荐
- XML 与 JSON 优劣对比
- As3.0 xml + Loader应用代码
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- ext读取两种结构的xml的代码
- 实例解析Ruby程序中调用REXML来解析XML格式数据的用法
- Ruby中XML格式数据处理库REXML的使用方法指南
- C#中如何使用 XmlReader 读取XML文件
- C#针对xml基本操作及保存配置文件应用实例
- Ruby使用REXML库来解析xml格式数据的方法
- Ruby程序中创建和解析XML文件的方法
- Ruby的XML格式数据解析库Nokogiri的使用进阶
- asp下查询xml的实现代码
- sqlserver FOR XML PATH 语句的应用
- 使用sp_xml_preparedocument处理XML文档的方法
- EBS xml publisher中文乱码问题及解决办法
- C#中的Linq to Xml详解
- C#操作XML文件实例汇总
- C# XML序列化方法及常用特性总结分析
- SQL Server中的XML数据进行insert、update、delete