在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使用socket远程连接错误处理方法
Apr 29 Python
编写Python小程序来统计测试脚本的关键字
Mar 12 Python
python列表的常用操作方法小结
May 21 Python
Python2随机数列生成器简单实例
Sep 04 Python
django 解决manage.py migrate无效的问题
May 27 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
Nov 07 Python
关于Pycharm无法debug问题的总结
Jan 19 Python
python算法题 链表反转详解
Jul 02 Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
Aug 13 Python
Python读取分割压缩TXT文本文件实例
Feb 14 Python
最小二乘法及其python实现详解
Feb 24 Python
python 装饰器功能与用法案例详解
Mar 06 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中isset()和unset()函数的用法小结
2014/03/11 PHP
PHP base64编码后解码乱码的解决办法
2014/06/19 PHP
php插入mysql数据返回id的方法
2018/05/31 PHP
jQuery参数列表集合
2011/04/06 Javascript
jQuery中closest()函数用法实例
2015/01/07 Javascript
js获取及修改网页背景色和字体色的方法
2015/12/29 Javascript
全面了解JS中的匿名函数
2016/06/29 Javascript
AngularJs定制样式插入到ueditor中的问题小结
2016/08/01 Javascript
获取JavaScript异步函数的返回值
2016/12/21 Javascript
javascript ASCII和Hex互转的实现方法
2016/12/27 Javascript
js如何判断是否在iframe中及防止网页被别站用iframe嵌套
2017/01/11 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
2017/03/08 Javascript
关于jQuery中fade(),show()起始位置的一点小发现
2017/04/25 jQuery
老生常谈js-react组件生命周期
2017/05/02 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
2018/10/17 NodeJs
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
浅谈ECMAScript 中的Array类型
2019/06/10 Javascript
移动端JS实现拖拽两种方法解析
2020/10/12 Javascript
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
Python登录注册验证功能实现
2018/06/18 Python
django queryset相加和筛选教程
2020/05/18 Python
初学者学习Python好还是Java好
2020/05/26 Python
Python实现爬取并分析电商评论
2020/06/19 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
2020/12/17 Python
html5 video标签屏蔽右键视频另存为的js代码
2013/11/12 HTML / CSS
html5写一个BUI折叠菜单插件的实现方法
2019/09/11 HTML / CSS
金融专业个人求职信范文
2013/11/28 职场文书
劳动模范事迹材料
2014/01/19 职场文书
《春笋》教学反思
2014/04/15 职场文书
班主任对学生的评语
2014/04/26 职场文书
幼儿园运动会口号
2014/06/07 职场文书
小学生国庆节演讲稿
2014/09/05 职场文书
小学思想品德教学反思
2016/02/24 职场文书
php引用传递
2021/04/01 PHP
js Proxy的原理详解
2021/05/25 Javascript