天天看点

Python3 xml解析模块xml.etree.ElementTree简介

xml.etree.ElementTree模块实现了一个解析和创建XML数据的简单而高效的API。XML是一种固有的分层数据格式,最自然的表示方法是使用树。xml.etree.ElementTree包含七个类以及若干函数用于操作xml。

说明
Element 表示一个xml元素。
ElementTree 表示整个xml文档。
QName 限定名包装器。
TreeBuilder 通用的元素构建器。
XMLParser 基于expat解析器的push解析器。
XMLPullParser 一个适合于非阻塞应用程序的pull解析器。
ParseError 表示解析XML文档时的错误。

通常,与整个文档的交互(读写文件)是用ElementTree完成的,与单个XML元素及其子元素的交互是用Element完成的。并不是输入xml的所有元素都会出现在最终的树中。目前会忽略输入xml中的注释、处理指令以及文档类型声明。但是可以使用API在构建的树中包含注释、处理指令,并输出到xml文件中。可以通过向XMLParser构造函数传递自定义的TreeBuilder实例来访问文档类型声明。

以下示例均基于test.xml文件:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>2011</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
           

解析

有两种简单的解析xml的方式:

1.从文件读取数据:

import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
           

2.从字符串读取:

import xml.etree.cElementTree as ET
root=ET.fromstring(xml_data_as_string)
           

 parse函数返回的是ElementTree对象,而fromstring函数返回的是Element对象。这两种方法解析xml都需要读取整个文档。可以通过XMLParser或XMLPullParser来增量的解析xml,但是XMLParser是阻塞的,而XMLPullParser是非阻塞的。

此外,还有带命名空间的xml解析。

创建

SubElement()函数提供了为给定元素创建新子元素的简便方法。

country=ET.SubElement(root,"country",attrib={"name":"Washington"})
rank=ET.SubElement(country,"rank",{"updated":"yes"})
rank.text="55"
gdppc=ET.SubElement(country,"gdppc")
gdppc.text="13600"
ET.dump(root)
           

查找

Element提供了一些实用的递归遍历子树(iter)、查找子树(find、findall)以及访问元素属性(get)。ElementTree支持部分xpath语法,可以使用更复杂的规则查找元素。

for neighbor in root.iter('neighbor'):
	print(neighbor.get("name"))
for country in root.findall("country"):
	print(country.get("name")+":"+country.find("rank").text)
           

修改

对xml的修改包括:直接修改字段值如text、tag、attrib、tail;使用set函数增加或修改属性;使用append函数添加新的子元素;使用remove函数删除子元素。并且ElementTree提供了wrtie函数可以非常方便的保存修改后的xml。

for country in root.iter('country'):
	rank=country.find("rank")
	rank.text=str(int(rank.text)+1)
	rank.set("updated","true")
	country.append(ET.Element("newTag",{"name":country.get("name")}))
tree=ET.ElementTree(root)
tree.write("out.xml");