Python ElementTree模块处理XML详解:解析、构造与节点操作
本文详解Python中[[wp:a0]]模块处理XML的核心方法。涵盖从文件与字符串解析XML、利用Element类构造文档、以及通过iter/findall查找和更新节点文本与属性,提供完整代码示例与注意事项。
前言
近期因工作需求,需使用Python发送SOAP请求以测试Web Service性能。鉴于SOAP基于XML协议,必须借助Python处理XML数据。经对比多种方案后,最终确定采用xml.etree.ElementTree 模块作为实现基础。
本文总结xml.etree.ElementTree 模块的常用操作,旨在梳理知识以备后续查阅,同时也供有相关需求的开发者参考学习。
概述
相较于Python中其他处理XML的方案,xml.etree.ElementTree 模块(下文简称为ET)具有接口简洁、易用性强的特点。
官方文档对ET模块有详细描述,其核心可归纳为三部分:ElementTree类、Element类以及若干XML操作函数。
XML本质上是树状结构。ET模块利用ElementTree类表示完整的XML文档,而使用Element类表示文档中的单个节点。通常,对整篇XML文档的操作针对ElementTree对象执行,而对具体节点的操作则针对Element对象进行。
解析XML文件
ET模块支持从XML文件构建ElementTree对象。以下示例中的XML文件example.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')
执行上述代码后,将生成一个名为a.xml的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
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









