Python利用ElementTree模块处理XML的方法详解
前言
最近因为工作的需要,在使用Python来发送SOAP请求以测试WebService的性能,由于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文档):
1 2008 141100 4 2011 59900
可以使用ET模块的parse()函数来从指定的XML文件构造一个ElementTree对象:
importxml.etree.ElementTreeasET #获取XML文档对象ElementTree tree=ET.parse('example.xml') #获取XML文档对象的根结点Element root=tree.getroot() #打印根结点的名称 printroot.tag
从XML文件构造好ElementTree对象后,还可以获取其结点,或者再继续对结点进行进一步的操作。
解析XML字符串
ET模块的fromstring()函数提供从XML字符串构造一个Element对象的功能。
xml_str=ET.tostring(root) printxml_str root=ET.fromstring(xml_str) printroot.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') printxml_str
输出:
leehao.mewww.leehao.me
如果需要输出到文件中,可以继续使用ElementTree.write()方法来处理:
#先构造一个ElementTree以便使用其write方法 tree=ET.ElementTree(a) tree.write('a.xml',encoding='UTF-8')
执行后,便会生成一个XML文件a.xml:
leehao.mewww.leehao.me
XML结点的查找与更新
1.查找XML结点
Element类提供了Element.iter()方法来查找指定的结点。Element.iter()会递归查找所有的子结点,以便查找到所有符合条件的结点。
#获取XML文档对象ElementTree tree=ET.parse('example.xml') #获取XML文档对象的根结点Element root=tree.getroot() #递归查找所有的neighbor子结点 forneighborinroot.iter('neighbor'): printneighbor.attrib
输出:
{'direction':'E','name':'Austria'} {'direction':'W','name':'Switzerland'} {'direction':'N','name':'Malaysia'}
如果使用Element.findall()或者Element.find()方法,则只会从结点的直接子结点中查找,并不会递归查找。
forcountryinroot.findall('country'): rank=country.find('rank').text name=country.get('name') printname,rank
输出:
Liechtenstein1 Singapore4
2.更新结点
如果需要更新结点的文本,可以通过直接修改Element.text来实现。如果需要更新结点的属性,可以通过直接修改Element.attrib来实现。
对结点进行更新后,可以使用ElementTree.write()方法将更新后的XML文档写入文件中。
#获取XML文档对象ElementTree tree=ET.parse('example.xml') #获取XML文档对象的根结点Element root=tree.getroot() forrankinroot.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文件以下:
2 2008 141100 5 2011 59900
对比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