Android网络编程之XML解析
来源:互联网 发布:mac口红免税店价格 编辑:程序博客网 时间:2024/06/06 13:56
一.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的。
- Android网络编程之sax解析xml
- Android网络编程之pull解析xml
- Android网络编程之XML解析
- android之网络编程解析XML
- android网络编程--xml解析
- Android网络编程之二:DOM解析XML文件
- Android网络编程之三:XmlPullParser解析Xml文件
- Android 网络编程之 XML 和 JSON 解析
- Android网络编程之解析XML格式数据
- Android网络编程之Pull解析XML文件
- 网络编程之android后台取服务器端xml解析之dom解析
- Android 网络获取数据之XML解析
- Android中级之网络数据解析一之xml解析
- 网络解析之xml
- Android网络编程之WebView【实例解析】
- Android网络编程之HttpUrlConnection【实例解析】
- Android网络编程之JSON解析
- Android网络之数据解析----SAX方式解析XML数据
- HDU 5011(博弈)
- SQL函数(二)
- java 线程synchronized 线程同步
- Java synchronized 关于…
- SQL 登陆
- Android网络编程之XML解析
- SQL时间查询和子查询
- SQL子查询
- 数字在排序数组中出现的次数
- IQKeyboardManager
- 用FileInputStream和FileOutputStream拷贝文件
- Linux网络编程--IO模型基础
- 一段代码 完全解读 SharedPreferedces。
- 主成分分析(Principal components analysis)-最大方差解释