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");