在Python中处理XML的教程


Posted in Python onApril 29, 2015

XML虽然比JSON复杂,在Web中应用也不如以前多了,不过仍有很多地方在用,所以,有必要了解如何操作XML。
DOM vs SAX

操作XML有两种方法:DOM和SAX。DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点。SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。

正常情况下,优先考虑SAX,因为DOM实在太占内存。

在Python中使用SAX解析XML非常简洁,通常我们关心的事件是start_element,end_element和char_data,准备好这3个函数,然后就可以解析xml了。

举个例子,当SAX解析器读到一个节点时:

<a href="/">python</a>

会产生3个事件:

  1.     start_element事件,在读取<a href="/">时;
  2.     char_data事件,在读取python时;
  3.     end_element事件,在读取</a>时。

用代码实验一下:

from xml.parsers.expat import ParserCreate

class DefaultSaxHandler(object):
  def start_element(self, name, attrs):
    print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))

  def end_element(self, name):
    print('sax:end_element: %s' % name)

  def char_data(self, text):
    print('sax:char_data: %s' % text)

xml = r'''<?xml version="1.0"?>
<ol>
  <li><a href="/python">Python</a></li>
  <li><a href="/ruby">Ruby</a></li>
</ol>
'''
handler = DefaultSaxHandler()
parser = ParserCreate()
parser.returns_unicode = True
parser.StartElementHandler = handler.start_element
parser.EndElementHandler = handler.end_element
parser.CharacterDataHandler = handler.char_data
parser.Parse(xml)

当设置returns_unicode为True时,返回的所有element名称和char_data都是unicode,处理国际化更方便。

需要注意的是读取一大段字符串时,CharacterDataHandler可能被多次调用,所以需要自己保存起来,在EndElementHandler里面再合并。

除了解析XML外,如何生成XML呢?99%的情况下需要生成的XML结构都是非常简单的,因此,最简单也是最有效的生成XML的方法是拼接字符串:

L = []
L.append(r'<?xml version="1.0"?>')
L.append(r'<root>')
L.append(encode('some & data'))
L.append(r'</root>')
return ''.join(L)

如果要生成复杂的XML呢?建议你不要用XML,改成JSON。
小结

解析XML时,注意找出自己感兴趣的节点,响应事件时,把节点数据保存起来。解析完毕后,就可以处理数据。

练习一下解析Yahoo的XML格式的天气预报,获取当天和最近几天的天气:

http://weather.yahooapis.com/forecastrss?u=c&w=2151330

参数w是城市代码,要查询某个城市代码,可以在weather.yahoo.com搜索城市,浏览器地址栏的URL就包含城市代码。

Python 相关文章推荐
Python 文件操作实现代码
Oct 07 Python
跟老齐学Python之玩转字符串(1)
Sep 14 Python
Python中的pprint折腾记
Jan 21 Python
从源码解析Python的Flask框架中request对象的用法
Jun 02 Python
详解Python之数据序列化(json、pickle、shelve)
Mar 30 Python
详解使用python的logging模块在stdout输出的两种方法
May 17 Python
python读取有密码的zip压缩文件实例
Feb 08 Python
使用django实现一个代码发布系统
Jul 18 Python
pycharm实现在虚拟环境中引入别人的项目
Mar 09 Python
接口自动化多层嵌套json数据处理代码实例
Nov 20 Python
pycharm配置python 设置pip安装源为豆瓣源
Feb 05 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
Mar 03 Python
python搜索指定目录的方法
Apr 29 #Python
python中sleep函数用法实例分析
Apr 29 #Python
介绍Python中内置的itertools模块
Apr 29 #Python
python使用fileinput模块实现逐行读取文件的方法
Apr 29 #Python
python将字符串转换成数组的方法
Apr 29 #Python
Python中使用hashlib模块处理算法的教程
Apr 28 #Python
简单介绍Python中的struct模块
Apr 28 #Python
You might like
php实现ping
2006/10/09 PHP
Zend Framework路由器用法实例详解
2016/12/11 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
添加JavaScript重载函数的辅助方法2
2010/07/04 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
基于jquery的滚动鼠标放大缩小图片效果
2011/10/27 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
2013/01/04 Javascript
原生js开发的日历插件
2017/02/04 Javascript
JavaScript轻松创建级联函数的方法示例
2017/02/10 Javascript
jQuery中clone()函数实现表单中增加和减少输入项
2017/05/13 jQuery
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
ES6中数组array新增方法实例总结
2017/11/07 Javascript
解决ng-repeat产生的ng-model中取不到值的问题
2018/10/02 Javascript
深入解析Vue源码实例挂载与编译流程实现思路详解
2019/05/05 Javascript
react-native滑动吸顶效果的实现过程
2019/06/03 Javascript
vue动态循环出的多个select出现过的变为disabled(实例代码)
2019/11/10 Javascript
[02:25]专访DOTA2负责人Erik 国际邀请赛暂不会离开西雅
2014/07/21 DOTA
paramiko模块安装和使用(远程登录服务器)
2014/01/27 Python
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
python 处理数字,把大于上限的数字置零实现方法
2019/01/28 Python
Python实现Event回调机制的方法
2019/02/13 Python
python如何修改文件时间属性
2021/02/05 Python
历史学专业毕业生求职信
2013/09/27 职场文书
先进工作者获奖感言
2014/02/08 职场文书
《老王》教学反思
2014/02/23 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
捐资助学倡议书
2014/04/15 职场文书
活动总结格式
2014/08/30 职场文书
党的群众路线对照检查材料思想汇报(学校)
2014/10/04 职场文书
大一学生个人总结
2015/02/15 职场文书
教师师德表现自我评价
2015/03/05 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
事业单位岗位说明书
2015/10/08 职场文书
2016暑期师德培训心得体会
2016/01/09 职场文书
正确的理解和使用Django信号(Signals)
2021/04/14 Python