在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实现的简单猜数字游戏
Apr 04 Python
python optparse模块使用实例
Apr 09 Python
Python的Django应用程序解决AJAX跨域访问问题的方法
May 31 Python
Django基础之Model操作步骤(介绍)
May 27 Python
python中import reload __import__的区别详解
Oct 16 Python
Python爬虫抓取代理IP并检验可用性的实例
May 07 Python
PySide和PyQt加载ui文件的两种方法
Feb 27 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
Aug 28 Python
Django实现文件上传和下载功能
Oct 06 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
Jan 04 Python
python实现简单贪吃蛇游戏
Sep 29 Python
Python实现学生管理系统并生成exe可执行文件详解流程
Jan 22 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 的ArrayAccess接口 像数组一样来访问你的PHP对象
2010/10/12 PHP
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
JavaScript CSS修改学习第五章 给“上传”添加样式
2010/02/19 Javascript
JavaScript中json使用自己总结
2013/08/13 Javascript
基于jQuery的JavaScript模版引擎JsRender使用指南
2014/12/29 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
2017/02/10 Javascript
angularJS+requireJS实现controller及directive的按需加载示例
2017/02/20 Javascript
JS区分Object与Aarry的六种方法总结
2017/02/27 Javascript
Javascript创建类和对象详解
2017/05/31 Javascript
vue 项目如何引入微信sdk接口的方法
2017/12/18 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
nodejs实现套接字服务功能详解
2018/06/21 NodeJs
vue富文本框(插入文本、图片、视频)的使用及问题小结
2018/08/17 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
JS实现躲避粒子小游戏
2020/06/18 Javascript
Vue中使用JsonView来展示Json树的实例代码
2020/11/16 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
Python中max函数用法实例分析
2015/07/17 Python
将Python代码打包为jar软件的简单方法
2015/08/04 Python
Python对象转换为json的方法步骤
2019/04/25 Python
在Python函数中输入任意数量参数的实例
2019/07/16 Python
解决Python 异常TypeError: cannot concatenate 'str' and 'int' objects
2020/04/08 Python
套娃式文件夹如何通过Python批量处理
2020/08/23 Python
Python基于execjs运行js过程解析
2020/11/27 Python
html5调用app分享功能示例(WebViewJavascriptBridge)
2018/03/21 HTML / CSS
美国保健品专家:Life Extension
2018/05/04 全球购物
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
C语言面试题
2015/10/30 面试题
绩效专员岗位职责
2013/12/02 职场文书
餐饮总经理岗位职责
2014/03/07 职场文书
感恩教育活动总结
2014/05/05 职场文书
优秀学生党员先进事迹材料
2014/05/29 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书
低版本Druid连接池+MySQL驱动8.0导致线程阻塞、性能受限
2021/07/01 MySQL