Android中XML解析
package com.example.thebroadproject; public class Book {
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;
} public void addPrice(){
price=price+1;
} @Override
public String toString() {
return "id:" + id + ", name:" + name + ", price:" + price;
}
}
第一种:DOM。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。
package com.example.thebroadproject; 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; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; public class DomBookParser { public List<Book> parse(InputStream is) throws Exception {
List<Book> books = new ArrayList<Book>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 取得DocumentBuilderFactory实例
DocumentBuilder builder = factory.newDocumentBuilder(); // 从factory获取DocumentBuilder实例
Document doc = builder.parse(is); // 解析输入流 得到Document实例
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;
} public String serialize(List<Book> books) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument(); // 由builder创建新文档 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 transFactory = TransformerFactory.newInstance();// 取得TransformerFactory实例
Transformer transformer = transFactory.newTransformer(); // 从transFactory获取Transformer实例
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明 StringWriter writer = new StringWriter(); Source source = new DOMSource(doc); // 表明文档来源是doc
Result result = new StreamResult(writer);// 表明目标结果为writer
transformer.transform(source, result); // 开始转换 return writer.toString();
} }
第二种:SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
package com.example.thebroadproject; 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; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler; public class SaxBookParser { public List<Book> parse(InputStream is) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance(); // 取得SAXParserFactory实例
SAXParser parser = factory.newSAXParser(); // 从factory获取SAXParser实例
MyHandler handler = new MyHandler(); // 实例化自定义Handler
parser.parse(is, handler); // 根据自定义Handler规则解析输入流
return handler.getBooks();
} public String serialize(List<Book> books) throws Exception {
SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();// 取得SAXTransformerFactory实例
TransformerHandler handler = factory.newTransformerHandler(); // 从factory获取TransformerHandler实例
Transformer transformer = handler.getTransformer(); // 从handler获取Transformer实例
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明 StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
handler.setResult(result); String uri = ""; // 代表命名空间的URI 当URI无值时 须置为空字符串
String localName = ""; // 命名空间的本地名称(不包含前缀) 当没有进行命名空间处理时 须置为空字符串 handler.startDocument();
handler.startElement(uri, localName, "books", null); AttributesImpl attrs = new AttributesImpl(); // 负责存放元素的属性信息
char[] ch = null;
for (Book book : books) {
attrs.clear(); // 清空属性列表
attrs.addAttribute(uri, localName, "id", "string", String.valueOf(book.getId()));// 添加一个名为id的属性(type影响不大,这里设为string)
handler.startElement(uri, localName, "book", attrs); // 开始一个book元素 关联上面设定的id属性 handler.startElement(uri, localName, "name", null); // 开始一个name元素 没有属性
ch = String.valueOf(book.getName()).toCharArray();
handler.characters(ch, 0, ch.length); // 设置name元素的文本节点
handler.endElement(uri, localName, "name"); handler.startElement(uri, localName, "price", null);// 开始一个price元素 没有属性
ch = String.valueOf(book.getPrice()).toCharArray();
handler.characters(ch, 0, ch.length); // 设置price元素的文本节点
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);
if (localName.equals("book")) {
book = new Book();
}
builder.setLength(0); // 将字符长度设置为0 以便重新开始读取元素内的字符节点
} @Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
builder.append(ch, start, length); // 将读取的字符数组追加到builder中
} @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
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);
}
}
}
}
第三种 PULL解析XML是在Android中用到的比较多,而且Android已经将PULL技术集成到了系统中,所以在使用PULL的时候不需要额外的引入到jar,Android中要是使用上述的四种方式,需要引入额外的jar,当然JavaEE中使用PULL技术进行解析的话,就需要引入PULL所需的jar了,其实PULL技术和SAX技术差不多,Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。
而他们的相似性在运行方式上,Pull解析器也提供了类似SAX的事件,开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等,但需要调用next() 方法提取它们(主动提取事件)。
Android系统中和Pull方式相关的包为org.xmlpull.v1,在这个包中提供了Pull解析器的工厂类XmlPullParserFactory和Pull解析器XmlPullParser,XmlPullParserFactory实例调用newPullParser方法创建XmlPullParser解析器实例,接着XmlPullParser实例就可以调用getEventType()和next()等方法依次主动提取事件,并根据提取的事件类型进行相应的逻辑处理。
package com.example.thebroadproject; import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer; import android.util.Xml; public class PullBookParser { public List<Book> parse(InputStream is) throws Exception {
List<Book> books = null;
Book book = null; XmlPullParser parser = Xml.newPullParser(); // 由android.util.Xml创建一个XmlPullParser实例
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;
} public String serialize(List<Book> books) throws Exception {
XmlSerializer serializer = Xml.newSerializer(); // 由android.util.Xml创建一个XmlSerializer实例
StringWriter writer = new StringWriter();
serializer.setOutput(writer); // 设置输出方向为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();
}
}
Android中XML解析的更多相关文章
- Android中XML解析-Dom解析
Android中需要解析服务器端传过来的数据,由于XML是与平台无关的特性,被广泛运用于数据通信中,有的时候需要解析xml数据,格式有三种方式,分别是DOM.SAX以及PULL三种方式,本文就简单以D ...
- Android中XML解析-SAX解析
昨天由于时间比较匆忙只写了Android中的XML解析的Dom方式,这种方式比较方便,很容易理解,最大的不足就是内容多的时候,会消耗内存.SAX(Simple API for XML)是一个解析速度快 ...
- Android中XML解析-PULL解析
前面写了两篇XML解析的Dom和SAX方式,Dom比较符合思维方式,SAX事件驱动注重效率,除了这两种方式以外也可以使用Android内置的Pull解析器解析XML文件. Pull解析器的运行方式与 ...
- Android中XML解析,保存的三种方法
简单介绍 在Android开发中,关于XML解析有三种方式,各自是: SAX 基于事件的解析器.解析速度快.占用内存少.非常适合在Android移动设备中使用. DOM 在内存中以树形结构存放,因此检 ...
- Android实现XML解析技术
转载:Android实现XML解析技术 本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为 ...
- 2016 - 1- 23 iOS中xml解析 (!!!!!!!有坑要解决!!!!!!)
一: iOS中xml解析的几种方式简介 1.官方原生 NSXMLParser :SAX方式解析,使用起来比较简单 2.第三方框架 libxml2 :纯C 同时支持DOM与SAX GDataXML: D ...
- Android中XML文件的序列化生成与解析
xml文件是非常常用的,在android中json和xml是非常常用的两种封装数据的形式,从服务器中获取数据也经常是这两种形式的,所以学会生成和解析xml和json是非常有用的,json相对来说是比较 ...
- Android中pull解析XML文件的简单使用
首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐 ...
- Android学习记录(1)—Android中XML文件的序列化生成与解析
xml文件是非常常用的,在android中json和xml是非常常用的两种封装数据的形式,从服务器中获取数据也经常是这两种形式的,所以学会生成和解析xml和json是非常有用的,json相对来说是比较 ...
随机推荐
- csuoj 1112: 机器人的指令
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1112 1112: 机器人的指令 Time Limit: 1 Sec Memory Limit: ...
- [原创]安装Oracle 11gR2,以及如何在win8下使用plsql develper连接Oracle数据库 ,在这里和大家分享下
一,关于win8下安装Oracle 11gR2 1.我下载的是Oracle_11gR2_win64.其中有两个包: 注意:在解压了之后将:win64_11gR2_database_2of2\datab ...
- android复习第二天------布局
1,在4,0版本前一共有五种布局,且都是ViewGroup的子类分别是 RelativeLayout(相对),AbsoluteLayout(绝对),LinearLayout(线性),FrameLayo ...
- Spark on Mesos部署
一.Mesos的安装和部署 1.下载mesos源码和依赖包 部署环境 centOS 6.6 mesos-0.21.0 spark-1.4.1 因为mesos官方只提供源码,所以必须要自己进行编译安装使 ...
- MVC4下拉少数名族
List<SelectListItem> nationlist = new List<SelectListItem>() { new SelectListItem(){Valu ...
- oracle 的索引
一.索引分类 按逻辑分: 单列索引(Single column): 单列索引是基于单列所创建的索引 复合(多列)索引(Concatenated ): 复合索引是基于两列或者多列所创建的索引 ...
- 夺命雷公狗ThinkPHP项目之----企业网站21之网站前台二级分类显示名称(TP自定义函数展示无限极分类)
我们实现网站二级分类的显示的时候,先要考虑的是直接取出顶级栏目,控制器代码如下所示: <?php namespace Home\Controller; use Think\Controller; ...
- yii2顶部导航使用
yii2中使用顶部导航的具体方法: 1.视图中调用两个类: use yii\bootstrap\Nav;use yii\bootstrap\NavBar; 2. <?php ...
- Openstack的HA解决方案【mysql集群配置】
使用mysql的galera做多主集群配置,galera的集群优势网络上面有对比,这里不在叙述. 1. 新建3台虚拟机(centos6.5) node1:172.17.44.163 node2:172 ...
- V4L2应用程序框架-二【转】
本文转载自:http://blog.csdn.net/tommy_wxie/article/details/11371439 V4L2驱动框架 主设备号: 81 次设备号: 0-63 64 ...