Xml解析之——Java/Android/Python
2015-12-14 16:38
639 查看
Xml解析之——Java/Android/Python
上面是一个简单的xml文件,个人的理解:xml文件是一个格式标准,代码清晰的树形结构体。
简单的介绍下集中解析方式
DOM:将整个XML文件解析到内存生成一个树形结构。
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
适用点:对象传输,全文件的数据修改等
SAX:基于事件驱动的,也就是说解析器去从xml文件的开始往下走,当发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
优点:不用事先调入整个文档,占用资源少
适用点:元素检索
PULL:运行方式和SAX类似,基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。
三、例子
我们就以操作test.xml为例。
假设我们要取test.xml中字节点remote的属性name的值
DOM和SAX是最常见的解写xml的方式,这里python实现,java的实现基本差别不大
我们以谷歌天气为例,这是我们从google官方网站上下载下来的xml格式的当天天气。
xml文件中参数比较多,我现在只想知道城市,温度,适度,风向四个值,建立一个数据结构CurrentWeatherXml来保存这四个值
我们建立一个Model类来做xml的处理,在这个类中,我们对xml文件进行解析,从中抽取城市,天气,湿度,风向,并将其值存入到CurrentWeatherXml中
然后,我们就可以将xml文件作为参数传递给WeatherXmlModel,WeatherXmlModer处理完毕后,得到我们需要的数据CurrentWeatherXml。
参考资料:
googleweatherapi : http://openweathermap.org/current http://blog.csdn.net/jdsjlzx/article/details/7215289 PULL解析google天气
一、Xml文件 test.xml
<note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> <remote name="origin" fetch="." review="gerrit.huaqin.com:8081" /> <default revision="pythontest" remote="origin" sync-j="4" /> </note>
上面是一个简单的xml文件,个人的理解:xml文件是一个格式标准,代码清晰的树形结构体。
二、Xml文件的解析
xml解析主要是有SAX和DOM ,python还另外提供了ElementTree(轻量级的DOM),android提供了PULL。简单的介绍下集中解析方式
DOM:将整个XML文件解析到内存生成一个树形结构。
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
适用点:对象传输,全文件的数据修改等
SAX:基于事件驱动的,也就是说解析器去从xml文件的开始往下走,当发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
优点:不用事先调入整个文档,占用资源少
适用点:元素检索
PULL:运行方式和SAX类似,基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。
三、例子
我们就以操作test.xml为例。
1.DOM(python实现)
__author__ = 'xuqiang' from xml.dom import minidom,Node #先将文件解析出来放在DOMTree中 DOMTree = minidom.parse("test.xml") #取根节点 note = DOMTree.documentElement length = len(note.childNodes) #依次取子节点 for child in note.childNodes: if child.nodeType == Node.COMMENT_NODE: print child.name + ':' + child.nodeValue elif child.nodeType == Node.ELEMENT_NODE: print "<%s>" % child.nodeName #取子就子节点属性 if child.hasAttributes(): attributes = child.attributes for index in range(attributes.length): print " %s = %s" % (attributes.item(index).name,attributes.item(index).value) #去子节点的文本 if child.hasChildNodes(): print "%s" % child.childNodes[0].data print "</%s>" % child.nodeName
2.SAX
SAX最佳使用的地方就是查找某个元素的值假设我们要取test.xml中字节点remote的属性name的值
__author__ = 'xuqiang' import xml import xml.sax class TestHandler(xml.sax.ContentHandler): def __init__(self): self.to = "" self.fromm = "" self.heading = "" self.body = "" self.review = "" self.name = "" self.fetch = "" self.remote = "" self.defaultremote = "" self.sync = "" self.revision = "" self.default = "" def startElement(self, tag, attributes): self.CurrentData = tag #找到节点remote的属性 name if tag == 'remote': print "remote name is %s" % attributes.get('name') def endElement(self, tag): if self.CurrentData == "to": print "to:", self.to elif self.CurrentData == "from": print "from:", self.fromm elif self.CurrentData == "heading": print "heading:", self.heading elif self.CurrentData == "body": print "body:", self.body elif self.CurrentData == "remote": print "remote:", self.remote elif self.CurrentData == "default": print "default:", self.default self.CurrentData = "" def characters(self, content): if self.CurrentData == "to": self.to = content elif self.CurrentData == "from": self.fromm = content elif self.CurrentData == "heading": self.heading = content elif self.CurrentData == "body": self.body = content elif self.CurrentData == "remote": self.remote = content elif self.CurrentData == "default": self.default = content parser = xml.sax.make_parser() parser.setFeature(xml.sax.handler.feature_namespaces, 0) Handler = TestHandler() parser.setContentHandler(Handler) parser.parse("test.xml")
DOM和SAX是最常见的解写xml的方式,这里python实现,java的实现基本差别不大
三、PULL
PULL是android中最常用的解析xml的方式。他的原理和SAX类似,是基于事件处理的。使用方法也类似。我们以谷歌天气为例,这是我们从google官方网站上下载下来的xml格式的当天天气。
<?xml version="1.0" encoding="utf-8"?> <current> <city id="1796236" name="Shanghai"> <coord lon="121.46" lat="31.22"/> <country>CN</country> <sun rise="2015-12-13T22:44:16" set="2015-12-14T08:52:49"/> </city> <temperature value="283.15" min="283.15" max="283.15" unit="kelvin"/> <humidity value="82" unit="%"/> <pressure value="1024" unit="hPa"/> <wind> <speed value="5" name="Gentle Breeze"/> <direction value="310" code="NW" name="Northwest"/> </wind> <clouds value="44" name="scattered clouds"/> <visibility value="5000"/> <precipitation mode="no"/> <weather number="721" value="haze" icon="50d"/> <lastupdate value="2015-12-14T03:00:00"/> </current>
xml文件中参数比较多,我现在只想知道城市,温度,适度,风向四个值,建立一个数据结构CurrentWeatherXml来保存这四个值
package org.xerrard.xmlpulldemo; public class CurrentWeatherXml { public String city; //城市 public String temperature; // 温度 public String humidity; // 湿度 public String wind_direction; // 风向 public String toString() { //摄氏度(℃)=K-273。 float s = Float.parseFloat(temperature); float temperatureC = s-273; StringBuilder sb = new StringBuilder(); sb.append(" 城市: ").append(city); sb.append(" 天气: ").append(temperature + "").append(" °K"); sb.append(" 天气: ").append(temperatureC + "").append(" °C"); sb.append(" 湿度 ").append(humidity); sb.append(" 风向 ").append(wind_direction); return sb.toString(); } }
我们建立一个Model类来做xml的处理,在这个类中,我们对xml文件进行解析,从中抽取城市,天气,湿度,风向,并将其值存入到CurrentWeatherXml中
package org.xerrard.xmlpulldemo; import java.io.InputStream; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import android.util.Log; public class WeatherXMLModel { public static CurrentWeatherXml curCondition = null; public static void initData(InputStream is){ try { if(is != 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: Log.d("xerrard", "START_DOCUMENT=" + parser.getName()); break; case XmlPullParser.START_TAG: String name = parser.getName(); if("current".equals(name)){//current标签 Log.d("xerrard", "START_TAG=" + name); curCondition = new CurrentWeatherXml(); }else if(curCondition != null){ if("city".equals(name)){ //city标签 curCondition.city = parser.getAttributeValue(1); } if("temperature".equals(name)){ //temperature标签 curCondition.temperature = parser.getAttributeValue(0); } if("humidity".equals(name)){ //humidity标签 curCondition.humidity = parser.getAttributeValue(0); } if("direction".equals(name)){ //direction标签 curCondition.wind_direction = parser.getAttributeValue(0); } } break; case XmlPullParser.END_TAG: if("forecast_conditions".equals(parser.getName())){ Log.d("xerrard", "END_TAG=" + parser.getName()); } break; } eventType = parser.next(); } Log.d("xerrard", "curCondition--" + curCondition); } } catch (Exception e) { e.printStackTrace(); } } }
然后,我们就可以将xml文件作为参数传递给WeatherXmlModel,WeatherXmlModer处理完毕后,得到我们需要的数据CurrentWeatherXml。
InputStream inputStream = new FileInputStream(xmlFlie); WeatherXMLModel.initData(inputStream); CurrentWeatherXml weather = WeatherXMLModel.curCondition; TextView hello = (TextView)findViewById(R.id.hello); hello.setText(weather.toString());
参考资料:
googleweatherapi : http://openweathermap.org/current http://blog.csdn.net/jdsjlzx/article/details/7215289 PULL解析google天气
相关文章推荐
- ADB(Android Debug Bridge) 的使用
- Android setImageResource、setImageBitmap、setImageDrawable区别
- TextView实现歌词同步
- Android 源码解析: 图片加载库Picasso 2 Cache机制
- android平台TextView使用ImageSpan画廊GIF图像
- SQLITE 在 ANDROID 中的详细使用
- 解决Android平台中应用程序OOM异常的方法
- Android ormlite升级数据库方案-KJFrameForAndroid升级Sqllite数据库
- Android圆形图/头像
- android中使用回调接口实现底部菜单的切换
- Android中定时执行任务的3种实现方法
- android 布局属性大全
- 自定义ProgressDialog
- 【Android】javadoc, Android注释中添加链接
- Android的SQLite
- 记录Android开发的点点滴滴
- Android --调启百度地图
- MPAndroidChart 教程:开始 Getting Started(一)
- Android中悬浮窗口
- android冷启动优化