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 中的列表解析和生成表达式
Mar 10 Python
Python操作Word批量生成文章的方法
Jul 28 Python
import的本质解析
Oct 30 Python
使用Django和Python创建Json response的方法
Mar 26 Python
使用Python写一个小游戏
Apr 02 Python
在python中使用requests 模拟浏览器发送请求数据的方法
Dec 26 Python
Python Flask 搭建微信小程序后台详解
May 06 Python
Python使用tkinter模块实现推箱子游戏
Oct 08 Python
sklearn-SVC实现与类参数详解
Dec 10 Python
Python list运算操作代码实例解析
Jan 20 Python
tensorflow如何继续训练之前保存的模型实例
Jan 21 Python
Python实现疫情通定时自动填写功能(附代码)
May 27 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读取文件内容的三种可行方法示例介绍
2014/02/08 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
php 读取输出其他文件的实现方法
2016/07/26 PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
2017/02/06 PHP
JQuery困惑—包装集 DOM节点
2009/10/16 Javascript
2则自己编写的jQuery特效分享
2015/02/26 Javascript
JQuery入门基础小实例(1)
2015/09/17 Javascript
jQuery根据name属性进行查找的用法分析
2016/06/23 Javascript
微信小程序 icon组件详细及实例代码
2016/10/25 Javascript
nodejs个人博客开发第六步 数据分页
2017/04/12 NodeJs
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
Python执行时间的计算方法小结
2017/03/17 Python
详解Django之admin组件的使用和源码剖析
2018/05/04 Python
python numpy 显示图像阵列的实例
2018/07/02 Python
pycharm打开命令行或Terminal的方法
2019/01/16 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
2019/11/19 Python
Windows下Pycharm远程连接虚拟机中Centos下的Python环境(图文教程详解)
2020/03/19 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
2021/01/29 Python
html5超简单的localStorage实现记住密码的功能实现
2017/09/07 HTML / CSS
巴西香水和化妆品购物网站:The Beauty Box
2019/09/03 全球购物
学期自我鉴定范文
2013/10/01 职场文书
银行员工辞职信范文
2014/01/20 职场文书
《学会合作》教学反思
2014/04/12 职场文书
落实八项规定专题民主生活会对照检查材料
2014/09/15 职场文书
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
软弱涣散基层党组织整改方案
2014/10/25 职场文书
2014年服务行业工作总结
2014/11/18 职场文书
2016党风廉政建设心得体会范文
2016/01/25 职场文书
React Hook用法示例详解(6个常见hook)
2021/04/28 Javascript
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
Python爬虫基础初探selenium
2021/05/31 Python
CSS实现背景图片全屏铺满自适应的3种方式
2022/07/07 HTML / CSS