Python利用ElementTree模块处理XML的方法详解


Posted in Python onAugust 31, 2017

前言

最近因为工作的需要,在使用 Python 来发送 SOAP 请求以测试 Web Service 的性能,由于 SOAP 是基于 XML 的,故免不了需要使用 python 来处理 XML 数据。在对比了几种方案后,最后选定使用 xml.etree.ElementTree 模块来实现。

这篇文章记录了使用 xml.etree.ElementTree 模块常用的几个操作,也算是总结一下,免得以后忘记了。分享出来也方法需要的朋友们参考学习,下面话不多说了,来一起看看详细的介绍吧。

概述

对比其他 Python 处理 XML 的方案,xml.etree.ElementTree 模块(下文我们以 ET 来表示)相对来说比较简单,接口也较友好。

官方文档 里面对 ET 模块进行了较为详细的描述,总的来说,ET 模块可以归纳为三个部分:ElementTree类,Element类以及一些操作 XML 的函数。

XML 可以看成是一种树状结构,ET 使用ElementTree类来表示整个 XML 文档,使用Element类来表示 XML 的一个结点。对整 XML 文档的操作一般是对ElementTree对象进行,而对 XML 结点的操作一般是对Element对象进行。

解析 XML 文件

ET 模块支持从一个 XML 文件构造ElementTree对象,例如我们的 XML 文件example.xml内容如下(下文会继续使用这个 XML 文档):

<?xml version="1.0" encoding="utf-8"?>
<data>
 <country name="Liechtenstein">
  <rank>1</rank>
  <year>2008</year>
  <gdppc>141100</gdppc>
  <neighbor name="Austria" direction="E"/>
  <neighbor name="Switzerland" direction="W"/>
 </country>
 <country name="Singapore">
  <rank>4</rank>
  <year>2011</year>
  <gdppc>59900</gdppc>
  <neighbor name="Malaysia" direction="N"/>
 </country>
</data>

可以使用 ET 模块的parse()函数来从指定的 XML 文件构造一个ElementTree对象:

import xml.etree.ElementTree as ET

# 获取 XML 文档对象 ElementTree
tree = ET.parse('example.xml')
# 获取 XML 文档对象的根结点 Element
root = tree.getroot()
# 打印根结点的名称
print root.tag

从 XML 文件构造好ElementTree对象后,还可以获取其结点,或者再继续对结点进行进一步的操作。

解析 XML 字符串

ET 模块的fromstring()函数提供从 XML 字符串构造一个Element对象的功能。

xml_str = ET.tostring(root)
print xml_str
root = ET.fromstring(xml_str)
print root.tag

接着上面的代码,我们使用 ET 模块的tostring()函数来将上面我们构造的root对象转化为字符串,然后使用fromstring()函数重新构造一个Element对象,并赋值给root变量,这时root代表整个 XML 文档的根结点。

构造 XML

如果我们需要构造 XML 文档,可以使用 ET 模块的 Element类以及SubElement()函数。

可以使用Element类来生成一个Element对象作为根结点,然后使用ET.SubElement()函数生成子结点。

a = ET.Element('a')
b = ET.SubElement(a, 'b')
b.text = 'leehao.me'
c = ET.SubElement(a, 'c')
c.attrib['greeting'] = 'hello'
d = ET.SubElement(a, 'd')
d.text = 'www.leehao.me'
xml_str = ET.tostring(a, encoding='UTF-8')
print xml_str

输出:

<?xml version='1.0' encoding='UTF-8'?>
<a><b>leehao.me</b><c greeting="hello" /><d>www.leehao.me</d></a>

如果需要输出到文件中,可以继续使用ElementTree.write()方法来处理:

# 先构造一个 ElementTree 以便使用其 write 方法
tree = ET.ElementTree(a)
tree.write('a.xml', encoding='UTF-8')

执行后,便会生成一个 XML 文件a.xml:

<?xml version='1.0' encoding='UTF-8'?>
<a><b>leehao.me</b><c greeting="hello" /><d>www.leehao.me</d></a>

XML 结点的查找与更新

1. 查找 XML 结点

Element类提供了Element.iter()方法来查找指定的结点。Element.iter()会递归查找所有的子结点,以便查找到所有符合条件的结点。

# 获取 XML 文档对象 ElementTree
tree = ET.parse('example.xml')
# 获取 XML 文档对象的根结点 Element
root = tree.getroot()
# 递归查找所有的 neighbor 子结点
for neighbor in root.iter('neighbor'):
 print neighbor.attrib

输出:

{'direction': 'E', 'name': 'Austria'}
{'direction': 'W', 'name': 'Switzerland'}
{'direction': 'N', 'name': 'Malaysia'}

如果使用Element.findall()或者Element.find()方法,则只会从结点的直接子结点中查找,并不会递归查找。

for country in root.findall('country'):
 rank = country.find('rank').text
 name = country.get('name')
 print name, rank

输出:

Liechtenstein 1
Singapore 4

2. 更新结点

如果需要更新结点的文本,可以通过直接修改Element.text来实现。如果需要更新结点的属性,可以通过直接修改Element.attrib来实现。

对结点进行更新后,可以使用ElementTree.write()方法将更新后的 XML 文档写入文件中。

# 获取 XML 文档对象 ElementTree
tree = ET.parse('example.xml')
# 获取 XML 文档对象的根结点 Element
root = tree.getroot()
for rank in root.iter('rank'):
 new_rank = int(rank.text) + 1
 rank.text = str(new_rank)
 rank.attrib['updated'] = 'yes'
tree.write('output.xml', encoding='UTF-8')

新生成的output.xml文件以下:

<?xml version='1.0' encoding='UTF-8'?>
<data>
 <country name="Liechtenstein">
  <rank updated="yes">2</rank>
  <year>2008</year>
  <gdppc>141100</gdppc>
  <neighbor direction="E" name="Austria" />
  <neighbor direction="W" name="Switzerland" />
 </country>
 <country name="Singapore">
  <rank updated="yes">5</rank>
  <year>2011</year>
  <gdppc>59900</gdppc>
  <neighbor direction="N" name="Malaysia" />
 </country>
</data>

对比example.xml文件,可以看到output.xml文件已更新。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

参考资料

  • https://docs.python.org/2/library/xml.html#xml-vulnerabilities
  • https://stackoverflow.com/questions/1912434/how-do-i-parse-xml-in-python
Python 相关文章推荐
用Python编写一个国际象棋AI程序
Nov 28 Python
用实例解释Python中的继承和多态的概念
Apr 27 Python
在Python的Django框架中编写错误提示页面
Jul 22 Python
Python的requests网络编程包使用教程
Jul 11 Python
python实现读取excel写入mysql的小工具详解
Nov 20 Python
pandas groupby 分组取每组的前几行记录方法
Apr 20 Python
pandas 条件搜索返回列表的方法
Oct 30 Python
Python 存储字符串时节省空间的方法
Apr 23 Python
python框架django项目部署相关知识详解
Nov 04 Python
Python中包的用法及安装
Feb 11 Python
Python进程的通信Queue、Pipe实例分析
Mar 30 Python
Python scrapy爬取起点中文网小说榜单
Jun 13 Python
go和python变量赋值遇到的一个问题
Aug 31 #Python
理解Python中的绝对路径和相对路径
Aug 30 #Python
python 递归遍历文件夹,并打印满足条件的文件路径实例
Aug 30 #Python
python递归打印某个目录的内容(实例讲解)
Aug 30 #Python
python-opencv在有噪音的情况下提取图像的轮廓实例
Aug 30 #Python
关于python的list相关知识(推荐)
Aug 30 #Python
Python编程实现正则删除命令功能
Aug 30 #Python
You might like
如何过滤高亮显示非法字符
2006/10/09 PHP
解决CodeIgniter伪静态失效
2014/06/09 PHP
基于PHP微信红包的算法探讨
2016/07/21 PHP
php实现数组中出现次数超过一半的数字的统计方法
2018/10/14 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
2010/03/02 Javascript
JS性能优化笔记搜索整理
2013/08/21 Javascript
javascript中字符串的定义示例代码
2013/12/19 Javascript
jquery form 加载数据示例
2014/04/21 Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
2015/05/12 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
2015/09/02 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
第三章之Bootstrap 表格与按钮功能
2016/04/25 Javascript
angular2倒计时组件使用详解
2017/01/12 Javascript
javascript数组去重常用方法实例分析
2017/04/11 Javascript
layui点击按钮添加可编辑的一行方法
2018/08/15 Javascript
从组件封装看Vue的作用域插槽的实现
2019/02/12 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
详细解读Python中的__init__()方法
2015/05/02 Python
Python 迭代器与生成器实例详解
2017/05/18 Python
对numpy中的transpose和swapaxes函数详解
2018/08/02 Python
使用python爬取微博数据打造一颗“心”
2019/06/28 Python
Python笔试面试题小结
2019/09/07 Python
Python日志logging模块功能与用法详解
2020/04/09 Python
Django nginx配置实现过程详解
2020/09/10 Python
10款最佳Python开发工具推荐,每一款都是神器
2020/10/15 Python
纯CSS3实现3D旋转书本效果
2016/03/21 HTML / CSS
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
HTML5的结构和语义(1):前言
2008/10/17 HTML / CSS
药品质量检测应届生求职信
2013/11/14 职场文书
建筑项目策划书
2014/01/13 职场文书
空乘英文求职信
2014/04/13 职场文书
2014年纳税评估工作总结
2014/12/23 职场文书
护理实习生带教计划
2015/01/16 职场文书
高二英语教学反思
2016/03/03 职场文书
Spring实现内置监听器
2021/07/09 Java/Android