Python 使用 ElementTree 模块来处理 XML

栏目: 编程语言 · XML · 发布时间: 7年前

内容简介:Python 使用 ElementTree 模块来处理 XML

最近使用 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 文件已更新。

参考资料

  1. https://docs.python.org/2/library/xml.html#xml-vulnerabilities
  2. https://stackoverflow.com/questions/1912434/how-do-i-parse-xml-in-python

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

世界因你不同:李开复自传(纪念版)

世界因你不同:李开复自传(纪念版)

李开复,范海涛 著作 / 中信出版社 / 2015-7-10 / 39.00

编辑推荐 1.李开复唯一一部描写全面生平事迹的传记:《世界因你不同:李开复自传》书中讲述了家庭教育培育的“天才少年”;学校教育塑造的“创新青年”,走入世界顶级大公司,苹果、微软、谷歌等亲历的风云内幕,岁月30载不懈奋斗、追求事业成功的辉煌历程。 2.娓娓道来、字字珠玑、可读性和故事性皆佳。李开复博士是青少年成长成才的励志偶像,年轻家长、学校教师阅读后也能从中得到感悟和启发。 3.......一起来看看 《世界因你不同:李开复自传(纪念版)》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器