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编程语言的35个与众不同之处(语言特征和使用技巧)
Jul 07 Python
Python判断文件和文件夹是否存在的方法
May 21 Python
Python首次安装后运行报错(0xc000007b)的解决方法
Oct 18 Python
浅谈Python基础—判断和循环
Mar 22 Python
在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法
Jun 18 Python
Python 中Django验证码功能的实现代码
Jun 20 Python
python接口自动化如何封装获取常量的类
Dec 24 Python
pytorch 使用加载训练好的模型做inference
Feb 20 Python
Python爬虫JSON及JSONPath运行原理详解
Jun 04 Python
如何用python处理excel表格
Jun 09 Python
Python下划线5种含义代码实例解析
Jul 10 Python
python中random模块详解
Mar 01 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
php使用curl抓取qq空间的访客信息示例
2014/02/28 PHP
php列出mysql表所有行和列的方法
2015/03/13 PHP
Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
2016/03/21 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
javascript高亮效果的二种实现方法
2008/09/14 Javascript
Mozilla 表达式 __noSuchMethod__
2009/04/05 Javascript
Prototype ObjectRange对象学习
2009/07/19 Javascript
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
jquery中邮箱地址 URL网站地址正则验证实例代码
2013/09/15 Javascript
js获取当前页面的url网址信息
2014/06/12 Javascript
jQuery带箭头提示框tooltips插件集锦
2014/11/17 Javascript
Jquery中offset()和position()的区别分析
2015/02/05 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
2015/04/26 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
浅谈javascript中执行环境(作用域)与作用域链
2016/12/08 Javascript
jquery中封装函数传递当前元素的方法示例
2017/05/05 jQuery
三种Webpack打包方式(小结)
2018/09/19 Javascript
ES6中的迭代器、Generator函数及Generator函数的异步操作方法
2019/05/12 Javascript
jQuery位置选择器用法实例分析
2019/06/28 jQuery
vue实现图片预览组件封装与使用
2019/07/13 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
对于Python深浅拷贝的理解
2019/07/29 Python
Python3标准库之functools管理函数的工具详解
2020/02/27 Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
2020/03/12 Python
Python函数参数分类原理详解
2020/05/28 Python
html5如何在Canvas中实现自定义路径动画示例
2017/09/18 HTML / CSS
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?
2016/08/13 面试题
出国导师推荐信
2014/01/16 职场文书
保健品市场营销方案
2014/03/31 职场文书
2014年第四季度入党积极分子思想汇报(十八届四中全会)
2014/11/03 职场文书
捐助倡议书
2015/01/19 职场文书
校园音乐节目广播稿
2015/08/19 职场文书
入党申请书怎么写?
2019/06/21 职场文书
mysql数据库隔离级别详解
2022/06/16 MySQL
详解flex:1什么意思
2022/07/23 HTML / CSS