一.XML的概念
- XML是一种用于标记电子文件使其具有结构性的标记语言。
- XML的设计宗旨是传输数据,而不是显示数据。
- XML是各种应用程序之间进行数据传输的最常用的工具。
二.XML的语法
- 任何的起始标签都必须有一个结束标签。
- 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如
<Android/>
。XML解析器会将其翻译成<Android></Android>
。 - 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
- 所有的特性都必须有值。
- 所有的特性都必须在值的周围加上双引号。
XML示例:
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
三.解析XML的常用方法及优缺点
下面提供一个天气获取网址:获取天气XML,下面将用这个网址提供的XML数据来编写示例代码。
准备工作:
1)获取天气XML数据输入流
别忘了添加网络访问权限:
<uses-permission android:name="android.permission.INTERNET"/>
获取数据使用的异步任务:
/**
* 异步任务
* 获取XML数据,并解析XML
*/
class WeatherTask extends AsyncTask<URL, Void, List<City>> {
@Override
protected List<City> doInBackground(URL... params) {
//获取XML数据的输入流
try {
HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
InputStream is = conn.getInputStream();
//开始解析XML
SaxWeatherParser swp = new SaxWeatherParser();
return swp.parse(is);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(List<City> cities) {
super.onPostExecute(cities);
//最终数据,这里仅作打印操作。
if (cities != null) {
Log.i("TAG", cities.toString());
}
}
}
2)创建天气实体类City
package xml.example.com.xmltest;
/**
* Created by Zz on 2015/9/11.
*/
public class City {
private String quName;
private String pyName;
private String cityname;
private String state1;
private String state2;
private String stateDetailed;
private String tem1;
private String tem2;
private String windState;
public String getQuName() {
return quName;
}
public void setQuName(String quName) {
this.quName = quName;
}
public String getPyName() {
return pyName;
}
public void setPyName(String pyName) {
this.pyName = pyName;
}
public String getCityname() {
return cityname;
}
public void setCityname(String cityname) {
this.cityname = cityname;
}
public String getState1() {
return state1;
}
public void setState1(String state1) {
this.state1 = state1;
}
public String getState2() {
return state2;
}
public void setState2(String state2) {
this.state2 = state2;
}
public String getStateDetailed() {
return stateDetailed;
}
public void setStateDetailed(String stateDetailed) {
this.stateDetailed = stateDetailed;
}
public String getTem1() {
return tem1;
}
public void setTem1(String tem1) {
this.tem1 = tem1;
}
public String getTem2() {
return tem2;
}
public void setTem2(String tem2) {
this.tem2 = tem2;
}
public String getWindState() {
return windState;
}
public void setWindState(String windState) {
this.windState = windState;
}
@Override
public String toString() {
return "City{" +
"quName='" + quName + '\'' +
", pyName='" + pyName + '\'' +
", cityname='" + cityname + '\'' +
", state1='" + state1 + '\'' +
", state2='" + state2 + '\'' +
", stateDetailed='" + stateDetailed + '\'' +
", tem1='" + tem1 + '\'' +
", tem2='" + tem2 + '\'' +
", windState='" + windState + '\'' +
'}';
}
}
Android中常用的四种XML解析方法:
1. SAX解析器
原理
SAX解析器是基于事件驱动的。他将XML文档转化为一系列的事件,然后由事件处理器来决定如何处理。这种模式主要是基于事件源和事件处理器的。
(能产生事件的对象是事件源,对事件做出响应处理的对象被叫做事件处理器)步骤
1)获取SAXParserFactory实例对象2)获取SAXParser实例对象
3)写一个handler继承DefaultHandler
5)把传入的InputStream和自己写的handler注册到SAXParser中
6)正式开始解析
2. DOM解析器
原理:
DOM解析器把整个XML文件全部加载到内存中,在内存中形成一个与XML文件结构相对应的节点树。特点:占用资源多,效率高。步骤:
1)获取DocumentBuilderFactory的实例对象2)获取DocumentBuilder的实例对象
3)获取Document的实例对象
4)获取Element的实例对象
5)获取所有节点NodeList
6)遍历并解析节点
准备工作同上,只需要修改异步任务中的解析部分。
将如下代码:
SAXWeatherParser swp = new SAXWeatherParser();
return swp.parse(is);
改为:
DOMWeatherParser dwp = new DOMWeatherParser();
return dwp.parse(is);
3. PULL解析器
原理:
Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。步骤:
1)获取XmlPullParserFactory实例对象
2)获取XmlPullParser 实例对象
3)设置输入流和编码
4)获取事件类型
5)根据事件类型循环解析
准备工作同上,只需要修改异步任务中的解析部分。
将如下代码:
DOMWeatherParser dwp = new DOMWeatherParser();
return dwp.parse(is);
改为:
PULLWeatherParser pwp = new PULLWeatherParser();
return pwp.parse(is);
4.Dom4j解析框架
Dom4j.jar官方下载地址:http://sourceforge.net/projects/dom4j/files/
dom4j1.6.1.jar百度云下载地址:dom4j1.6.1下载
简介:
Dom4j是dom4j.org出品的一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。步骤:
这里主要介绍String转Java bean用法,其他用法参见官方文档。这里提供一个1.6.1版本的文档下载链接:dom4j-1.6.1 docs
1)获取SAXReader实例对象
2)获取Document实例对象
3)获取Element的实例对象
4)获取所有节点NodeList
5)遍历并解析节点
可见, 和DOM解析器步骤相似。
准备工作同上,修改异步任务如下:
PULLWeatherParser pwp = new PULLWeatherParser();
return pwp.parse(is);
改为
Dom4jWeatherParser d4wp = new Dom4jWeatherParser();
return d4wp.parse(is);
四.使用SAX解析XML
SAX解析代码如下:
package xml.example.com.xmltest;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
* Created by Zz on 2015/9/11.
*/
public class SAXWeatherParser {
/**
* 解析过程
* @param is 输入流
* @return 集合
*/
public List<City> parse(InputStream is) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
WeatherHandler handler = new WeatherHandler();
parser.parse(is, handler);
is.close();
return handler.getCities();
}
/**
* 继承DefaultHandler,具体解析方式都在这里面。
* 需要实现5个最重要的方法。
*/
private class WeatherHandler extends DefaultHandler {
private List<City> cities;
private City city;
//此处不需要tagName,这个是为characters方法使用的。
private String tagName;
/**
* 返回解析后各城市天气集合
* @return 集合
*/
public List<City> getCities() {
return cities;
}
//接收文档开始的通知。当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
@Override
public void startDocument() throws SAXException {
super.startDocument();
//初始化集合
cities = new ArrayList<City>();
}
//接收元素开始的通知。当遇到元素的开头的时候,调用这个方法。
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (localName.equals("city")) {
city = new City();
//根据属性值获取数据
city.setQuName(attributes.getValue("quName"));
city.setPyName(attributes.getValue("pyName"));
city.setCityname(attributes.getValue("cityname"));
city.setState1(attributes.getValue("state1"));
city.setState2(attributes.getValue("state2"));
city.setStateDetailed(attributes.getValue("stateDetailed"));
city.setTem1(attributes.getValue("tem1"));
city.setTem2(attributes.getValue("tem2"));
city.setWindState(attributes.getValue("windState"));
}
tagName = localName;
}
//接收字符数据的通知。当遇到字符数据的时候,调用这个方法。如<string>hello</string>中的hello就是字符数据。
//本例中不需要使用此方法。因为没有上述字符数据。
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
//接收元素结尾的通知。当遇到元素结尾的时候,调用这个方法。
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if (localName.equals("city")) {
cities.add(city);
city = null;
}
this.tagName = null;
}
//接收文档结尾的通知。当遇到文档结尾的时候,调用这个方法。一般可以不用写。这里仅作说明用。
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}
}
调用代码在MainActivity实现如下:
private List<City> cities;
private static final String WEATHER_URL = "http://flash.weather.com.cn/wmaps/xml/china.xml";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动异步任务,开始获取数据并解析数据
try {
new WeatherTask().execute(new URL(WEATHER_URL));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
解析结果如下:
09-11 12:53:06.923 31095-31095/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat
(注:由于Log信息太长,且未换行,未能显示完整。实际上已经全部解析出来了。)
五.使用DOM解析XML
DOM解析代码如下:
package xml.example.com.xmltest;
import android.util.Log;
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.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
* Created by Zz on 2015/9/11.
*/
public class DOMWeatherParser {
/**
* 解析过程
* @param is 输入流
* @return 集合
* @throws Exception 异常
*/
public List<City> parse(InputStream is) throws Exception{
List<City> cities = new ArrayList<City>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
Element element = document.getDocumentElement();
//得到所有city节点
NodeList items = element.getElementsByTagName("city");
//遍历city节点
for (int i=0; i<items.getLength();i++) {
City city = new City();
//得到第一个city节点
Element item = (Element) items.item(i);
//获取节点的属性值
city.setQuName(item.getAttribute("quName"));
city.setPyName(item.getAttribute("pyName"));
city.setCityname(item.getAttribute("cityname"));
city.setState1(item.getAttribute("state1"));
city.setState2(item.getAttribute("state2"));
city.setStateDetailed(item.getAttribute("stateDetailed"));
city.setTem1(item.getAttribute("tem1"));
city.setTem2(item.getAttribute("tem2"));
city.setWindState(item.getAttribute("windState"));
//将节点添加到集合
cities.add(city);
}
return cities;
}
}
解析结果如下:
09-11 14:18:59.333 19643-19643/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat
六.使用PULL解析XML
PULL解析代码如下:
package xml.example.com.xmltest;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Zz on 2015/9/11.
*/
public class PULLWeatherParser {
public List<City> parse(InputStream is) throws Exception {
List<City> cities = null;
City city = null;
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
parser.setInput(is, "UTF-8");
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
//初始化工作
cities = new ArrayList<City>();
break;
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals("city")) {
city = new City();
city.setQuName(parser.getAttributeValue(null, "quName"));
city.setPyName(parser.getAttributeValue(null, "pyName"));
city.setCityname(parser.getAttributeValue(null, "cityname"));
city.setState1(parser.getAttributeValue(null, "state1"));
city.setState2(parser.getAttributeValue(null, "state2"));
city.setStateDetailed(parser.getAttributeValue(null, "stateDetailed"));
city.setTem1(parser.getAttributeValue(null, "tem1"));
city.setTem2(parser.getAttributeValue(null, "tem2"));
city.setWindState(parser.getAttributeValue(null, "windState"));
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("city") && city != null && cities != null) {
//添加节点到集合
cities.add(city);
}
break;
}
//下一个节点
eventType = parser.next();
}
return cities;
}
}
解析结果如下:
09-11 15:32:00.202 12176-12176/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='9', windState='北风4-5级转3-4级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='9', windState='北风转西北风3-4级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='1', state2='1', stateDetailed='多云', tem1='24', tem2='11', windState='北风3-4级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='32', tem2='25', windState='东风3-4级'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='0', stateDetailed='多云转晴', tem1='16', tem2='5', windState='西北风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='26', tem2='18', windState='东南风6-7级'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='7', stateDetailed='阴转小雨', tem1='23', tem2='11', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='15', tem2='4', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='1', state2='0', stateDetailed='多云转晴', tem1='21', tem2='7', windState='北风4-5级转微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='1', state2='0', stateDetailed='多云转晴', tem1='20', tem2='9', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='15', windState='西北风3-4级转4-5级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='2', state2='1', stateDetailed='阴转多云', tem1='24', tem2='16', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='27', tem2='19', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='31', tem2='22', windState='北风小于3级'}, City{quName='山东', pyName='shandong', cityname='济南', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='20', tem2='14', windState='北风小于3级转3-4级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='2', state2='2', stateDetailed='阴', tem1='27', tem2='20', windState='东北风小于3级转北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='28', tem2='20', windState='北风小于3级转3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='0', stateDetailed='多云转晴', tem1='22', tem2='9', windState='西北风4-5级转3-4级'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='1', state2='0', stateDetailed='多云转晴', tem1='26', tem2='15', windState='东北风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='25', tem2='19', windState='南风小于3级'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='1', state2='9', stateDetailed='多云转大雨', tem1='25', tem2='15', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='3', state2='3', stateDetailed='阵雨', tem1='23', tem2='16', windState='东南风转东北风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='0', state2='1', stateDetailed='晴转多云', tem1='29', tem2='20', windState='东北风小于3级转3-4级'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='1', stateDetailed='多云', tem1='31', tem2='22', windState='东风3-4级转微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='0', state2='1', stat
七.使用Dom4j解析XML
Dom4j解析代码如下:
package xml.example.com.xmltest;
import android.util.Log;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Zz on 2015/9/23.
*/
public class Dom4jWeatherParser {
/**
* 解析过程
* @param is 输入流
* @return 集合
* @throws Exception 异常
*/
@SuppressWarnings("unchecked")
public List<City> parse(InputStream is) throws Exception {
List<City> cities = new ArrayList<City>();
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(is);
//获取根节点
Element root = document.getRootElement();
//获取子节点
List<Element> elements = root.elements();
for (int i =0 ;i < elements.size(); i++) {
City city = new City();
Element item = elements.get(i);
//获取节点的属性值
city.setQuName(item.attributeValue("quName"));
city.setPyName(item.attributeValue("pyName"));
city.setCityname(item.attributeValue("cityname"));
city.setState1(item.attributeValue("state1"));
city.setState2(item.attributeValue("state2"));
city.setStateDetailed(item.attributeValue("stateDetailed"));
city.setTem1(item.attributeValue("tem1"));
city.setTem2(item.attributeValue("tem2"));
city.setWindState(item.attributeValue("windState"));
//将节点添加到集合
cities.add(city);
}
return cities;
}
}
Dom4j解析结果如下:
09-23 19:58:35.908 758-758/xml.example.com.xmltest I/TAG﹕ [City{quName='黑龙江', pyName='heilongjiang', cityname='哈尔滨', state1='1', state2='1', stateDetailed='多云', tem1='8', tem2='18', windState='东北风转东风小于3级'}, City{quName='吉林', pyName='jilin', cityname='长春', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='9', tem2='21', windState='东北风小于3级'}, City{quName='辽宁', pyName='liaoning', cityname='沈阳', state1='3', state2='1', stateDetailed='阵雨转多云', tem1='12', tem2='25', windState='东北风转东南风小于3级'}, City{quName='海南', pyName='hainan', cityname='海口', state1='1', state2='1', stateDetailed='多云', tem1='25', tem2='33', windState='微风'}, City{quName='内蒙古', pyName='neimenggu', cityname='呼和浩特', state1='1', state2='1', stateDetailed='多云', tem1='8', tem2='19', windState='西风小于3级'}, City{quName='新疆', pyName='xinjiang', cityname='乌鲁木齐', state1='0', state2='0', stateDetailed='晴', tem1='7', tem2='18', windState='微风'}, City{quName='西藏', pyName='xizang', cityname='拉萨', state1='2', state2='3', stateDetailed='阴转阵雨', tem1='11', tem2='22', windState='微风'}, City{quName='青海', pyName='qinghai', cityname='西宁', state1='7', state2='7', stateDetailed='小雨', tem1='5', tem2='15', windState='微风'}, City{quName='宁夏', pyName='ningxia', cityname='银川', state1='2', state2='1', stateDetailed='阴转多云', tem1='10', tem2='21', windState='微风'}, City{quName='甘肃', pyName='gansu', cityname='兰州', state1='7', state2='1', stateDetailed='小雨转多云', tem1='10', tem2='22', windState='微风'}, City{quName='河北', pyName='hebei', cityname='石家庄', state1='1', state2='1', stateDetailed='多云', tem1='17', tem2='27', windState='微风转南风小于3级'}, City{quName='河南', pyName='henan', cityname='郑州', state1='7', state2='7', stateDetailed='小雨', tem1='19', tem2='23', windState='微风'}, City{quName='湖北', pyName='hubei', cityname='武汉', state1='2', state2='7', stateDetailed='阴转小雨', tem1='20', tem2='24', windState='微风'}, City{quName='湖南', pyName='hunan', cityname='长沙', state1='1', state2='2', stateDetailed='多云转阴', tem1='22', tem2='31', windState='微风'}, City{quName='山东', pyName='shandong', cityname='济南', state1='1', state2='1', stateDetailed='多云', tem1='20', tem2='28', windState='南风小于3级'}, City{quName='江苏', pyName='jiangsu', cityname='南京', state1='1', state2='2', stateDetailed='多云转阴', tem1='20', tem2='27', windState='东北风3-4级'}, City{quName='安徽', pyName='anhui', cityname='合肥', state1='1', state2='7', stateDetailed='多云转小雨', tem1='20', tem2='28', windState='东风小于3级转东北风3-4级'}, City{quName='山西', pyName='shanxi', cityname='太原', state1='1', state2='2', stateDetailed='多云转阴', tem1='12', tem2='25', windState='微风'}, City{quName='陕西', pyName='sanxi', cityname='西安', state1='21', state2='2', stateDetailed='小到中雨转阴', tem1='15', tem2='22', windState='东风小于3级'}, City{quName='四川', pyName='sichuan', cityname='成都', state1='7', state2='7', stateDetailed='小雨', tem1='19', tem2='23', windState='微风'}, City{quName='云南', pyName='yunnan', cityname='昆明', state1='3', state2='3', stateDetailed='阵雨', tem1='17', tem2='25', windState='微风'}, City{quName='贵州', pyName='guizhou', cityname='贵阳', state1='2', state2='3', stateDetailed='阴转阵雨', tem1='19', tem2='24', windState='南风小于3级'}, City{quName='浙江', pyName='zhejiang', cityname='杭州', state1='2', state2='1', stateDetailed='阴转多云', tem1='20', tem2='28', windState='微风'}, City{quName='福建', pyName='fujian', cityname='福州', state1='1', state2='3', stateDetailed='多云转阵雨', tem1='24', tem2='31', windState='微风'}, City{quName='江西', pyName='jiangxi', cityname='南昌', state1='1', state2='1', stateDetailed='多云', tem1='22', tem2='29', windState='微风'}, City{quName='广东', pyName='guangdong', cityname=
八.总结
四种解析器各有各的优缺点,那么使用的时候应该如何抉择呢?
首先总结一下四者的优缺点:
1)SAX:一次性解析整个文档,不能中途停止。内存占用较少。解析速度快,但代码比较繁琐。
2)DOM:整个文件读入内存,所以较大的XML文件会占用大量内存。解析速度慢,但可以提取想要的内容。
3)PULL:可以通过程序控制在哪里停止解析。可控性强。内存占用较少。解析速度快,代码更简洁。
4)Dom4j:性能非常好,灵活性高,易使用。代码简介。
综上,Dom4j , SAX,PULL所占内存少,更适合移动设备的XML解析,如果硬要在Dom4j、SAX和PULL中抉择,我觉得Dom4j和PULL都可以。虽然DOM占用内存大,但这并不代表DOM就不能在Android设备上使用,在解析小文件且需要反复检索时,还是可以考虑使用DOM解析XML的。另外,Dom4j底层也是基于SAX和DOM的。