在android开发中服务器端返回的XML数据是很常见的,这里主要介绍XML的解析方式
XML的解析方式主要分为两个大类:
1.基于文档驱动,在解析XML文档前需要把整个文档储存到内存中。如:DOM
2.基于时间驱动,根据不同的需求事件执行不同的解析操作。如:SAX、PULL
首先我们先创建一个XML数据文件,books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<name>西游记</name>
<author>吴承恩</author>
</book>
<book id="2">
<name>三国演义</name>
<author>罗贯中</author>
</book>
<book id="3">
<name>红楼梦</name>
<author>曹雪斤</author>
</book>
<book id="4">
<name>水浒传</name>
<author>施耐庵</author>
</book>
</books>
一、DOM
DOM解析器先加载整个XML文档到内存中,然后解析全部文件,并将文件分为独立的元素、属性等,以树结构的形式存在于内存中,允许开发人员使用DOM API遍历XML树,根据需要搜索数据或修改文档
try {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document d=db.parse("src/com/yuong/xml/books.xml");
//通过Document对象的getElementsByTagName()返根节点的一个list集合
NodeList books=d.getElementsByTagName("book");
System.out.println("books length : "+books.getLength());
for(int i=0;i<books.getLength();i++) {
Node book=books.item(i);
//解析book节点的子节点
NodeList childlist = book.getChildNodes();
for(int n=0;n<childlist.getLength();n++) {
Node child=childlist.item(n);
//区分出text类型的node以及element类型的node
if(child.getNodeType() == Node.ELEMENT_NODE){
System.out.print(child.getNodeName()+":");
System.out.println(child.getTextContent());
}
}
System.out.println("---------------------------");
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DOM的优缺点及应用场景
1.整个文档以树结构的形式在内存中,操作整个文档的效率高,便于删除、修改、检索等操作
2.文件比较大时,整个文档加载到内存中,耗内存比较大,解析效率低,浪费空间资源
应用场景:XML文档较小,资源比较充足(如内存、CPU),频繁操作解析文档或多次访问这些数据
二、SAX
SAX解析器是按顺序扫描XML文档,是边扫描边解析的。当扫面到Document、Element开始或结束标签时,便会调用相应的方法,并且状态信息以参数的形式传递到方法中,开发者可以根据状态信息执行相关的自定义操作
//自定义一个解析XML数据Handler
public class SaxHandler extends DefaultHandler {
private String name;
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
//super.startDocument();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
//super.startElement(uri, localName, qName, attributes);
this.name=qName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
//super.characters(ch, start, length);
String data = new String(ch, start, length);
if(data!=null&&!data.equals("")&&!data.trim().equals("")) {
System.out.println(name+" : "+data);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
name=null;
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
}
}
//接下来,调用实现
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
SaxHandler handler = new SaxHandler();
sp.parse("src/com/yuong/xml/books.xml", handler);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SAX的优缺点及应用场景
1.解析速度快,占用内存少。非常适合在Android移动设备中使用
2.灵活性高,解析过程中通过回调把tag/value值等传给你,你可以比较、操作
3.解析方法复杂,代码量大,每解析一类XML,就要编写一个新的适合该类XML的处理类
4.可拓展性差,SAX并没有提供对文档中加节点的API,更没有删除,修改文档内容的方法
应用场景:XML文档较大,解析性能要求高,多次访问这些数据
三、PULL
PULL解析器解析解析流程类似Sax的解析流程,提供了开始文档、结束文档、开始元素和结束元素等标记让开发者进行判断,使用parse.nextText()方法获取相应元素字符数据。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码
FileInputStream inputStream=null;
try {
//创建生产XML的pull解析器的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
//使用工厂获取pull解析器
XmlPullParser parser = factory.newPullParser();
//获取输入流
inputStream=new FileInputStream(new File("src/com/yuong/xml/books.xml"));
//设置流和字符集
parser.setInput(inputStream, "utf-8");
//开始解析
int type = parser.getEventType();
while(type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_DOCUMENT: //开始读取XML文档
// TODO 实例化集合类
break;
case XmlPullParser.START_TAG:
if(parser.getName().equals("book")){
}else if(parser.getName().equals("name")){
String name=parser.nextText();
System.out.print(name+" : ");
}else if(parser.getName().equals("author")){
String author=parser.nextText();
System.out.println(author);
}
break;
case XmlPullParser.END_TAG:
break;
default:
break;
}
type=parser.next();
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(inputStream!=null) {
inputStream.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
PULL的优缺点及应用场景
1.解析速度快,占用内存少,比SAX简单。非常适合在Android移动设备中使用
2.灵活性高,可以控制事件处理结束的时机
3.可拓展性差,SAX并没有提供对文档中加节点的API,更没有删除,修改文档内容的方法
应用场景:XML文档较大,解析性能要求高,多次访问这些数据,需要控制事件处理结束时机的情况
三、XML和JSON
XML的优缺点
优点:
(1)格式统一,符合标准;
(2)容易与其他系统进行远程交互,数据传输比较方便。
缺点:
(1)XML文件庞大,文件格式复杂,传输占带宽;
(2)服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
(3)客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
(4)服务器端和客户端解析XML花费较多的资源和时间。
JSON的优缺点
优点:
(1)数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;
(2)易于解析,客户端JavaScript可以简单的通过eval_r()进行JSON数据的读取;
(3)支持多种语言,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;
(4)在PHP世界,已经有PHP-JSON和JSON-PHP出现了,偏于PHP序列化后的程序直接调用,PHP服务器端的对象、数组等能直接生成JSON格式,便于客户端的访问提取;
(5)因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
缺点:
(1) 没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;
(2)JSON格式目前在Web Service中推广还属于初级阶段
XML和JSON的优缺点对比
(1)在可读性方面,JSON和XML的数据可读性基本相同。JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,很难分出胜负。
(2)在可扩展性方面,XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。
(3)在编码难度方面,XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。
(4)在解码难度方面,XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。
(5)在流行度方面,XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。
(6) JSON和XML同样拥有丰富的解析手段。
(7)JSON相对于XML来讲,数据的体积小。
(8)JSON与JavaScript的交互更加方便。
(9)JSON对数据的描述性比XML较差。
(10)JSON的速度要远远快于XML。