Python中xml.etree.ElementTree模块使用及常用函数介绍
[id_182639910]id_205067083]

ET 用 Element 来表示 xml 里的节点、文本以及注释等。它的主要属性情况如下:
tag 是一个 string 对象,它表示数据所代表的种类。当这个数据代表节点时,它就是节点的名称。
text:string对象,表示element的内容。
attrib:dictionary对象,表示附有的属性。
tail 是一个 string 对象,它表示 element 闭合之后所留下的尾迹。
若干子元素(child elements)。
texttail
1 3 2 4
ET 模块对那些恶意构造的数据而言并不安全。如果需要解析数据,最好了解一下 xml 的弱点[2]。
一、导入ET
Python标准库中,ElementTree存在两种实现方式。其一为纯 Python 的实现 xml.etree.ElementTree,其二是速度更快一些的 xml.etree.cElementTree。倘若不确定环境中是否具备 cElementTree,那么可以采用如下的方式进行导入。
try:
导入 xml.etree.cElementTree 并将其命名为 ET 。
except ImportError:
导入 xml.etree.ElementTree 并将其重命名为 ET 。
从 Python 3.3 起,会默认采用 cElementTree 以加快速度。而在之前的版本中,最好使用上述那样的代码,这样能提高代码的兼容性。
二、解析xml
假设我们现在有如下的xml
1
2008
141100
4
2011
59900
68
2011
13600
有两种方式可以解析xml
1. 从文件中解析xml文件
引入 xml.etree.ElementTree 并将其重命名为 ET 。
xmlPath 等于将字符串“G:\text.img.xml”转换为 Unicode 编码,编码方式为“utf-8”
xml = ET.parse(xmlPath)
或
导入 xml.etree.cElementTree 并将其命名为 ET 。
tree 是通过 file='doc1.xml' 来载入数据的。
获取根节点的操作是 root = tree.getroot() 。
2. 从内存字符串中解析xml
使用 ET 从 country_data_as_string 中创建出 root 。
其中第二种方式可以直接过去根节点。
三、数据的访问
>>> for child in root:
输出 child 的标签(child.tag)以及 child 的属性(child.attrib)。
...
这个国家的名称是列支敦士登。
这个国家的名字是新加坡。
这个国家的名字是巴拿马。 巴拿马是一个国家。 它的名字被称作巴拿马。 巴拿马这个名字属于一个国家。 有一个国家叫巴拿马。 存在一个名为巴拿马的国家。 一个国家的名字为巴拿马。 名叫巴拿马的是一个国家。 某个国家的名字是巴拿马。 有某个国家叫巴拿马。 存在某个名为巴拿马的国家。 有那样一个国家叫巴拿马。 存在那样一个名为巴拿马的国家。 有这样一个国家叫巴拿马。 存在这样一个名为巴拿马的国家。 有这一国家叫巴拿马。 存在这一名为巴拿马的国家。 有该国家叫巴拿马。 存在该名为巴拿马的国家。 有那个国家叫巴拿马。 存在那个名为巴拿马的国家。 有那国家叫巴拿马。 存在那名为巴拿马的国家。 有此国家叫巴拿马。 存在此名为巴拿马的国家。 有一国家叫巴拿马。 存在一名为巴拿马的国家。 有个国家叫巴拿马。 存在个名为巴拿马的国家。 有某国家叫巴拿马。 存在某名为巴拿马的国家。 有一特定国家叫巴拿马。 存在一特定名为巴拿马的国家。 有特定国家叫巴拿马。 存在特定名为巴拿马的国家。 有某特定国家叫巴拿马。 存在某特定名为巴拿马的国家。 有特定的国家叫巴拿马。 存在特定的名为巴拿马的国家。 有那特定国家叫巴拿马。 存在那特定名为巴拿马的国家。 有那特定的国家叫巴拿马。 存在那特定的名为巴拿马的国家。 有此特定国家叫巴拿马。 存在此特定名为巴拿马的国家。 有特定的一国家叫巴拿马。 存在特定的一名为巴拿马的国家。 有特定的某国家叫巴拿马。 存在特定的某名为巴拿马的国家。 有特定的某一国家叫巴拿马。 存在特定的某一名为巴拿马的国家。 有特定的某个国家叫巴拿马。 存在特定的某个名为巴拿马的国家。 有特定的那国家叫巴拿马。 存在特定的那名为巴拿马的国家。 有特定的那特定国家叫巴拿马。 存在特定的那特定名为巴拿马的国家。 有特定的此国家叫巴拿马。 存在特定的此名为巴拿马的国家。 有特定的这国家叫巴拿马。 存在特定的这名为巴拿马的国家。 有特定的这特定国家叫巴拿马。 存在特定的这特定名为巴拿马的国家。 有特定的那特定的国家叫巴拿马。 存在特定的那特定的名为巴拿马的国家。 有特定的此特定的国家叫巴拿马。 存在特定的此特定的名为巴拿马的国家。 有特定的这一特定国家叫巴拿马。 存在特定的这一特定名为巴拿马的国家。 有特定的某一特定国家叫巴拿马。 存在特定的某一特定名为巴拿马的国家。 有特定的某个特定国家叫巴拿马。 存在特定的某个特定名为巴拿马的国家。 有特定的那某特定国家叫巴拿马。 存在特定的那某特定名为巴拿马的国家。 有特定的此某特定国家叫巴拿马。 存在特定的此某特定名为巴拿马的国家。 有特定的这某特定国家叫巴拿马。 存在特定的这某特定名为巴拿马的国家。 有特定的那特定一国家叫巴拿马。 存在特定的那特定一名为巴拿马的国家。 有特定的此特定一国家叫巴拿马。 存在特定的此特定一名为巴拿马的国家。 有特定的某特定一国家叫巴拿马。 存在特定的某特定一名为巴拿马的国家。 有特定的那某特定一国家叫巴拿马。 存在特定的那某特定一名为巴拿马的国家。 有特定的此某特定一国家叫巴拿马。 存在特定的此某特定一名为巴拿马的国家。
或者直接使用索引寻找子节点:
>>> root[0][1].text
'2008'
可以使用 xpath 方式进行遍历,不过它只支持部分 xpath 方法。若想查看其支持的 xpath,请参照点我。
在根节点中查找所有名为“country”的子节点下的名为“neighbor”的子节点。
[, , , , ]
四、 处理xml流
以下程序会在读取 xml 文件的同时进行解析,当遇到标签开始或者标签结束时,就会返回相应的事件。
在对 sys.argv[2] 进行迭代解析时,对于每一个事件 event 和元素 elem ,会进行相应的操作。
if event == 'end':
如果 elem 的标签是 'location' 并且 elem 的文本是 'Zimbabwe' :
count += 1
清除元素。(将元素丢弃。)
这个程序在检查到标签结束时,会对指定的标签进行计数。最后的 elem.clear() 这一操作,确保了在解析完成之后能够尽快地释放内存。
五、Element对象
创建一个名为 xml.etree.ElementTree.Element 的类的实例,该实例的标签为 tag,属性为 attrib={},并且可以包含其他额外的参数 **extra
元素所代表的数据种类由 tag:string 来表示。
text:string 元素的内容。
tail:string 元素的尾形。
元素所具有的属性的字典。
#针对属性的操作
清空元素的 tail 并将其设置为 None。
获取 key 所对应的属性值,如果该属性不存在,就返回 default 值。
items()会根据属性字典来返回一个列表,这个列表中的元素是由(key, value)组成的。
返回的是包含所有元素属性键的一个列表。
设置一个新的属性键,并为其赋予相应的值。
#针对后代的操作
添加直系子元素。
将一串元素对象作为子元素进行增加。这是 Python2.7 的新特性。
寻找第一个匹配的子元素,其匹配对象可以是标签(tag)或者路径(path)。
寻找所有匹配子元素,这些子元素的匹配对象可以是 tag 或者 path。
寻找第一个匹配的子元素,然后返回它的 text 值。匹配的对象可以是 tag 或者 path。
在指定的位置插入一个子元素。
生成一个迭代器,这个迭代器可以遍历当前元素的所有后代,或者遍历给定 tag 的后代。 # python2.7 新特性
根据 path 查找所有的后代。
遍历所有后代并获取其 text 值的是 itertext()。
删除一个元素,这个元素被称为子元素。
六、ElementTree对象
创建一个 ElementTree 对象,可以传入一个 element 或者一个 file 参数。如果传入 element,则直接使用该 element 创建对象;如果传入 file,则从指定的文件中读取 element 来创建对象。
如果给定了 element,那么它就是新的 ElementTree 的根节点。
用给定的 element 来替换当前的根节点,使用时需谨慎。
以下方法和 Element 类中的同名方法相近似,不同之处在于它们把根节点当作操作对象。
find(match)
findall(match)
findtext(match, default=None)
iter(tag=None)
iterfind(match)
装载 xml 对象,其中 source 可以是文件名,也可以是文件类型对象。
getroot() 获取根节点
使用指定的编码“us-ascii”、无 XML 声明、无默认命名空间,以“xml”方法将内容写入文件。
七、模块方法-->用于生成xml文件
创建一个特别的 element。通过标准序列化,这个 element 能够代表一个 comment。comment 可以是 bytestring 或者 unicode。
ET.Comment(text=None)
生成一个 element tree,然后通过 sys.stdout 进行输出。这里的 elem 可以是元素树,也可以是单个元素。这种方法最好仅用于调试。
ET.dump(elem)
text 是一个字符串,此字符串包含 XML 数据。它与 XML()方法相似,能够返回一个 Element 实例。
ET.fromstring(text)
从字符串的序列对象里去解析 xml 文档。默认的 parser 是 XMLParser,然后会返回一个 Element 实例。在 V2.7 中新增了一些属性。
使用 ET 从序列中创建对象,其中序列通过 stringlist 提供,并且可以指定一个解析器(parser),如果未指定则使用默认解析器。
5.检查是否是一个element对象。
ET.iselement(element)
将文件或包含 xml 数据的文件对象解析为 element tree 并递增进行,同时报告进度。其中,events 是一个汇报列表,若忽略该列表,那么只会汇报出 end 事件。
注意,iterparse()只有在看见开始标签的“>”符号时才会抛出 start 事件。所以届时属性已经被定义了,然而 text 和 tail 属性在那时尚未被定义,同样子元素也未被定义,因此它们可能无法被显示出来。若想要完整的元素,请查找 end 事件。
使用 ET.iterparse 函数,传入 source 参数,同时 events 参数和 parser 参数可以为 None 。
7.将一个文件或者字符串解析为element tree。
ET.parse(source, parser=None)
这个方法会创建一个独特的 element 。这个 element 会被序列化为一个 xml 处理命令。
ET.ProcessingInstruction 针对目标进行操作,且文本可以为 None。
注册命名空间前缀,此注册在全局范围内有效,任何已给出的前缀或者命名空间 uri 的映射关系都会被删除,这是 V2.7 新加的属性。
ET 对命名空间进行注册,其前缀为 prefix,对应的 uri 为 uri 。
子元素工厂会创建一个 Element 实例,然后将其追加到已知的节点上。
ET 中的 SubElement 方法用于在 parent 元素下创建一个 tag 元素,同时可以设置 attrib 属性,还可以传入额外的参数 **extra 。
生成一个字符串以表示 xml 的 element,此 element 包含所有子元素,该 element 是 Element 实例,method 可为"xml"、"html"或"text",最终返回包含 xml 数据的字符串。
使用指定的编码“us-ascii”和方法“xml”,对 element 调用 tostring 方法,返回的结果为 ET 的字符串表示形式。
生成一个用于表示 xml 的 element 的字符串,该 element 包含所有子元素。element 是 Element 实例,method 为"xml"、"html"或"text"。返回一个包含了 xml 数据的字符串列表。这是 V2.7 新添加的属性。
使用“us-ascii”编码和“xml”方法的 ET.tostringlist 函数,传入参数 element 来获取字符串列表。
从一个字符串常量里把 xml 片段解析出来。然后返回一个 Element 实例。
ET.XML(text, parser=None)
从字符串常量中解析出 xml 片段,并且会返回一个字典,这个字典可以用来将 element 的 id 映射到其自身。
ET.XMLID(text, parser=None)