Xml解析之——Java/Android/Python
Xml解析之——Java/Android/Python
一、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天气
Xml解析之——Java/Android/Python的更多相关文章
- XML解析详解|乐字节
大家好,乐字节的小乐又来了,Java技术分享哪里少的了小乐!上次我们说了可扩展标记语言XML之二:XML语言格式规范.文档组成,本文将介绍重点——XML解析. 基本的解析方式有两种:一种叫 SAX ...
- 【Android】实现XML解析的几种技术
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- JAVA基础学习之XMLCDATA区、XML处理指令、XML约束概述、JavaBean、XML解析(8)
1.CDATA区在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理.遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直 ...
- android XMl 解析神奇xstream 六: 把集合list 转化为 XML文档
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
- android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
- android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
- android XML解析器全解案例
1.使用pull解析 package com.example.myxml; import java.io.InputStream; import java.util.ArrayList; import ...
- Android中级之网络数据解析一之xml解析
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! --Comic Sans MS Xml解析具有跨平台性,语言无关性,易操作性,因此广受开发者的欢迎. ...
- Android实现XML解析技术
转载:Android实现XML解析技术 本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为 ...
随机推荐
- Pots
poj3414:http://poj.org/problem?id=3414 题意:给你两个罐子的体积,然后让你只用这两个罐子量出给定k体积的水.题解:这里可以把两个罐子看成是一个二维的图,然后体积的 ...
- 了解运行时类型信息(RTTI)
RTTI需要引用单元TypeInfo GetPropInfo 函数用于获得属性的 RTTI 指针 PPropInfo.它有四种重载形式,后面三种重载的实现都是调用第一种形式.AKinds 参数用于限制 ...
- TWinControl的DoubleBuffered属性的作用与举例
留个爪,网上搜一篇,仔细分析一下.
- LNMP搭建(CentOS 6.3+Nginx 1.2.0+PHP 5.3.15(fpm)+ MySQL 5.5.35)
Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 ...
- LightOJ 1422 Halloween Costumes(记忆化搜索)
题意:给你n天分别要穿的衣服,可以套着穿,但是一旦脱下来就不能再穿了,问这n天要准备几件衣服. =============================================== ...
- iOS 用CocoaPods做iOS程序的依赖管理
文档更新说明 2012-12-02 v1.0 初稿 2014-01-08 v1.1 增加设置 ruby 淘宝源相关内容 2014-05-25 v2.0 增加国内 spec 镜像.使用私有 pod.po ...
- linux运维社区站点收集
1, 新世纪linux社区 offical locator: http://www.21ops.com/industry-news/24370.html 2,
- windows下python安装paramiko
Python中使用SSH需要用到OpenSSH,而OpenSSH依赖于paramiko模块,而paramiko模块又依赖于pycrypto模块,因此要在Python中使用SSH,则需要先安装模块顺序是 ...
- Paxos算法 Paxos Made Simple
Paxos算法 Paxos Made Simple Leslie Lamport 2001.11.1 简介 Paxos算法,纯文本方式描述,非常简单. 1 介绍 为 实现具有容错能力的分布式系统而提出 ...
- android 客户端 和 新浪微博如何打通的
微博SDK 为开发者 提供访问oauth2.0 授权认证,并集合sso登录功能,使用第三方应用可通过 新浪微博的 登录操作 提供微博分享功能,可直接通过微博客户端分享微博 名词解释 AppKey 分配 ...