Skip to main content

20.5. xml.etree.ElementTree — ElementTree XML API

源代码: Lib/xml/etree/ElementTree.py


xml.etree.ElementTree 模块实现用于解析和创建XML数据的简单有效的API。

在 3.3 版更改: 此模块将在可用时使用快速实施。 xml.etree.cElementTree 模块已弃用。

警告

xml.etree.ElementTree 模块对于恶意构造的数据不安全。如果需要解析不受信任或未经身份验证的数据,请参阅 XML漏洞

20.5.1. 教程

这是一个使用 xml.etree.ElementTree (简称 ET)的简短教程。目标是演示模块的一些构建块和基本概念。

20.5.1.1. XML树和元素

XML是一种固有的分层数据格式,最自然的方式来表示它是一棵树。为此,ET 有两个类–ElementTree 将整个XML文档表示为树,Element 表示此树中的单个节点。与整个文档的交互(从文件读取和写入文件)通常在 ElementTree 级别上进行。与单个XML元素及其子元素的交互是在 Element 级别上完成的。

20.5.1.2. 解析XML

我们将使用以下XML文档作为本节的示例数据:

<?xml version="1.0"?>
<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>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

我们可以通过从文件中读取来导入这些数据:

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

或者直接从一个字符串:

root = ET.fromstring(country_data_as_string)

fromstring() 将字符串中的XML直接解析为 ElementElement 是解析的树的根元素。其他解析函数可以创建 ElementTree。检查文档以确保。

作为 Elementroot 有一个标签和一个属性字典:

>>> root.tag
'data'
>>> root.attrib
{}

它也有孩子节点,我们可以迭代:

>>> for child in root:
...     print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

子节点是嵌套的,我们可以通过索引访问特定的子节点:

>>> root[0][1].text
'2008'

注解

不是所有的XML输入元素都将作为解析树的元素。目前,此模块跳过输入中的任何XML注释,处理指令和文档类型声明。然而,使用此模块的API而不是从XML文本解析构建的树可以有注释和处理指令;它们将在生成XML输出时包括。可以通过将定制 TreeBuilder 实例传递给 XMLParser 构造函数来访问文档类型声明。

20.5.1.3. Pull API用于非阻塞解析

该模块提供的大多数解析函数要求在返回任何结果之前立即读取整个文档。可以逐渐使用 XMLParser 和feed数据,但它是一个push API,它调用回调目标上的方法,这对于大多数需求来说太低级和不方便。有时用户真正想要的是能够解析XML增量,而不阻塞操作,同时享受完全构造的 Element 对象的方便。

最强大的工具是 XMLPullParser。它不需要阻塞读取来获取XML数据,而是使用 XMLPullParser.feed() 调用递增地提供数据。要获取解析的XML元素,请调用 XMLPullParser.read_events()。这里是一个例子:

>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
...     print(event)
...     print(elem.tag, 'text=', elem.text)
...
end

明显的使用情况是以非阻塞方式操作的应用程序,其中XML数据从套接字接收或从一些存储设备递增地读取。在这种情况下,阻塞读取是不可接受的。

因为它是如此灵活,XMLPullParser 可能不方便使用更简单的用例。如果你不介意你的应用程序阻塞读取XML数据,但仍希望有增量解析功能,请看看 iterparse()。当你正在阅读一个大的XML文档,并且不想把它完全保存在内存中时,它是有用的。

20.5.1.4. 寻找有趣的元素

Element 有一些有用的方法,有助于递归地遍历它下面的所有子树(它的孩子,他们的孩子,等等)。例如,Element.iter():

>>> for neighbor in root.iter('neighbor'):
...     print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}

Element.findall() 只找到具有当前元素的直接子元素的标签的元素。 Element.find() 找到具有特定标签的 first 子代,Element.text 访问元素的文本内容。 Element.get() 访问元素的属性:

>>> for country in root.findall('country'):
...     rank = country.find('rank').text
...     name = country.get('name')
...     print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68

通过使用 XPath,可以更复杂地规定要查找哪些元素。

20.5.1.5. 修改XML文件

ElementTree 提供了一种构建XML文档并将其写入文件的简单方法。 ElementTree.write() 方法用于此目的。

一旦创建,可以通过直接改变其字段(例如 Element.text),添加和修改属性(Element.set() 方法),以及添加新的子节点(例如利用 Element.append())来操纵 Element 对象。

假设我们要为每个国家的排名添加一个,并向rank元素添加一个 updated 属性:

>>> for rank in root.iter('rank'):
...     new_rank = int(rank.text) + 1
...     rank.text = str(new_rank)
...     rank.set('updated', 'yes')
...
>>> tree.write('output.xml')

我们的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>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

我们可以使用 Element.remove() 删除元素。假设我们要移除排名高于50的所有国家/地区:

>>> for country in root.findall('country'):
...     rank = int(country.find('rank').text)
...     if rank > 50:
...         root.remove(country)
...
>>> tree.write('output.xml')

我们的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>
</data>

20.5.1.6. 构建XML文档

SubElement() 函数还为给定元素创建新的子元素提供了一种方便的方法:

>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>

20.5.1.7. 使用命名空间解析XML

如果XML输入具有 命名空间,则具有形式 prefix:sometag 的前缀的标签和属性被扩展到 {uri}sometag,其中 prefix 被完全 URI 替换。此外,如果存在 默认命名空间,则将完整URI添加到所有非前缀标记之前。

这里是一个XML示例,它包含两个命名空间,一个前缀为“fictional”,另一个作为默认命名空间:

<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
        xmlns="http://people.example.com">
    <actor>
        <name>John Cleese</name>
        <fictional:character>Lancelot</fictional:character>
        <fictional:character>Archie Leach</fictional:character>
    </actor>
    <actor>
        <name>Eric Idle</name>
        <fictional:character>Sir Robin</fictional:character>
        <fictional:character>Gunther</fictional:character>
        <fictional:character>Commander Clement</fictional:character>
    </actor>
</actors>

搜索和探索此XML示例的一种方法是手动将URI添加到 find()findall() 的xpath中的每个标记或属性:

root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
    name = actor.find('{http://people.example.com}name')
    print(name.text)
    for char in actor.findall('{http://characters.example.com}character'):
        print(' |-->', char.text)

搜索命名空间XML示例的更好方法是创建具有自己的前缀的字典,并在搜索功能中使用这些前缀:

ns = {'real_person': 'http://people.example.com',
      'role': 'http://characters.example.com'}

for actor in root.findall('real_person:actor', ns):
    name = actor.find('real_person:name', ns)
    print(name.text)
    for char in actor.findall('role:character', ns):
        print(' |-->', char.text)

这两种方法都输出:

John Cleese
 |--> Lancelot
 |--> Archie Leach
Eric Idle
 |--> Sir Robin
 |--> Gunther
 |--> Commander Clement

20.5.1.8. 其他资源

有关教程和指向其他文档的链接,请参阅 http://effbot.org/zone/element-index.htm

20.5.2. XPath支持

此模块为 XPath表达式 在树中定位元素提供有限的支持。目标是支持缩写语法的一小部分;一个完整的XPath引擎超出了模块的范围。

20.5.2.1. 例

这里有一个例子演示了模块的一些XPath功能。我们将使用 解析XML 部分中的 countrydata XML文档:

import xml.etree.ElementTree as ET

root = ET.fromstring(countrydata)

# Top-level elements
root.findall(".")

# All 'neighbor' grand-children of 'country' children of the top-level
# elements
root.findall("./country/neighbor")

# Nodes with name='Singapore' that have a 'year' child
root.findall(".//year/..[@name='Singapore']")

# 'year' nodes that are children of nodes with name='Singapore'
root.findall(".//*[@name='Singapore']/year")

# All 'neighbor' nodes that are the second child of their parent
root.findall(".//neighbor[2]")

20.5.2.2. 支持的XPath语法

句法

含义

tag

选择具有给定标签的所有子元素。例如,spam 选择所有名为 spam 的子元素,spam/egg 在所有名为 spam 的子代中选择所有名为 egg 的子孙。

*

选择所有子元素。例如,*/egg 选择所有名为 egg 的孙子。

.

选择当前节点。这在路径的开始是最有用的,以指示它是相对路径。

//

在当前元素下的所有级别上选择所有子元素。例如,.//egg 选择整个树中的所有 egg 元素。

..

选择父元素。如果路径尝试到达start元素(元素 find 被调用)的祖先,则返回 None

[@attrib]

选择具有给定属性的所有元素。

[@attrib='value']

选择给定属性具有给定值的所有元素。该值不能包含引号。

[tag]

选择具有名为 tag 的子项的所有元素。只支持直系儿童。

[tag='text']

选择具有名为 tag 的子级的所有元素,其完整文本内容(包括后代)等于给定的 text

[position]

选择位于给定位置的所有元素。位置可以是整数(1是第一位置),表达式 last() (对于最后一个位置)或相对于最后一个位置的位置(例如 last()-1)。

谓词(方括号中的表达式)前面必须有标记名称,星号或其他谓词。 position 谓词前必须有标记名称。

20.5.3. 参考

20.5.3.1. 功能

xml.etree.ElementTree.Comment(text=None)

评论元素工厂。这个工厂函数创建一个特殊的元素,它将被标准序列化序列化为一个XML注释。注释字符串可以是字节表或Unicode字符串。 text 是包含注释字符串的字符串。返回表示注释的元素实例。

注意,XMLParser 跳过输入中的注释,而不是为它们创建注释对象。 ElementTree 将只包含注释节点,如果它们已经使用 Element 方法之一插入到树中。

xml.etree.ElementTree.dump(elem)

将元素树或元素结构写入sys.stdout。此函数仅用于调试。

确切的输出格式取决于实现。在这个版本中,它被写成一个普通的XML文件。

elem 是元素树或单个元素。

xml.etree.ElementTree.fromstring(text)

从字符串常量解析XML部分。与 XML() 相同。 text 是一个包含XML数据的字符串。返回 Element 实例。

xml.etree.ElementTree.fromstringlist(sequence, parser=None)

从一系列字符串片段中解析XML文档。 sequence 是包含XML数据片段的列表或其他序列。 parser 是可选的解析器实例。如果没有给出,则使用标准 XMLParser 解析器。返回 Element 实例。

3.2 新版功能.

xml.etree.ElementTree.iselement(element)

检查对象是否显示为有效的元素对象。 element 是一个元素实例。如果这是元素对象,则返回true值。

xml.etree.ElementTree.iterparse(source, events=None, parser=None)

将XML部分以递增方式解析到元素树中,并向用户报告发生了什么。 source 是包含XML数据的文件名或 file objectevents 是要报告的事件序列。支持的事件是字符串 "start""end""start-ns""end-ns" (“ns”事件用于获取详细的命名空间信息)。如果省略 events,则仅报告 "end" 事件。 parser 是可选的解析器实例。如果未给出,则使用标准 XMLParser 解析器。 parser 必须是 XMLParser 的子类,并且只能使用默认 TreeBuilder 作为目标。返回提供 (event, elem) 对的 iterator

注意,虽然 iterparse() 以增量方式构建树,但它会阻止对 source (或其名称的文件)的读取。因此,它不适用于不能进行块读取的应用程序。有关完全非阻塞解析,请参阅 XMLPullParser

注解

iterparse() 只保证当它发出一个“开始”事件时它已经看到起始标签的“>”字符,因此定义了属性,但是文本和尾部属性的内容在该点是未定义的。这同样适用于元素儿;它们可以存在或可以不存在。

如果您需要一个完全填充的元素,请查找“结束”事件。

3.4 版后已移除: parser 参数。

xml.etree.ElementTree.parse(source, parser=None)

将XML部分解析到元素树中。 source 是包含XML数据的文件名或文件对象。 parser 是可选的解析器实例。如果没有给出,则使用标准 XMLParser 解析器。返回 ElementTree 实例。

xml.etree.ElementTree.ProcessingInstruction(target, text=None)

PI元件工厂。这个工厂函数创建一个将被序列化为XML处理指令的特殊元素。 target 是包含PI目标的字符串。 text 是包含PI内容的字符串(如果给出)。返回表示处理指令的元素实例。

注意,XMLParser 跳过输入中的处理指令,而不是为它们创建注释对象。 ElementTree 将只包含处理指令节点,如果它们已经使用 Element 方法之一插入到树中。

xml.etree.ElementTree.register_namespace(prefix, uri)

注册命名空间前缀。注册表是全局的,并且将删除给定前缀或命名空间URI的任何现有映射。 prefix 是命名空间前缀。 uri 是一个命名空间uri。此命名空间中的标签和属性将使用给定的前缀进行序列化,如果可能的话。

3.2 新版功能.

xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

工厂。此函数创建元素实例,并将其附加到现有元素。

元素名称,属性名称和属性值可以是bytestrings或Unicode字符串。 parent 是父元素。 tag 是子元素名称。 attrib 是一个可选的字典,包含元素属性。 extra 包含作为关键字参数给出的附加属性。返回元素实例。

xml.etree.ElementTree.tostring(element, encoding="us-ascii", method="xml", *, short_empty_elements=True)

生成XML元素的字符串表示形式,包括所有子元素。 elementElement 实例。 encoding [1] 是输出编码(默认为US-ASCII)。使用 encoding="unicode" 生成Unicode字符串(否则生成一个字节)。 method"xml""html""text" (默认值是 "xml")。 short_empty_elements 具有与 ElementTree.write() 中相同的含义。返回包含XML数据的(可选)编码字符串。

3.4 新版功能: short_empty_elements 参数。

xml.etree.ElementTree.tostringlist(element, encoding="us-ascii", method="xml", *, short_empty_elements=True)

生成XML元素的字符串表示形式,包括所有子元素。 elementElement 实例。 encoding [1] 是输出编码(默认为US-ASCII)。使用 encoding="unicode" 生成Unicode字符串(否则生成一个字节)。 method"xml""html""text" (默认值是 "xml")。 short_empty_elements 具有与 ElementTree.write() 中相同的含义。返回包含XML数据的(可选)编码字符串的列表。它不保证任何特定的序列,除了 b"".join(tostringlist(element)) == tostring(element)

3.2 新版功能.

3.4 新版功能: short_empty_elements 参数。

xml.etree.ElementTree.XML(text, parser=None)

从字符串常量解析XML部分。此函数可用于在Python代码中嵌入“XML文字”。 text 是包含XML数据的字符串。 parser 是可选的解析器实例。如果没有给出,则使用标准 XMLParser 解析器。返回 Element 实例。

xml.etree.ElementTree.XMLID(text, parser=None)

从字符串常量解析XML部分,并返回一个从元素id:s映射到元素的字典。 text 是包含XML数据的字符串。 parser 是可选的解析器实例。如果没有给出,则使用标准 XMLParser 解析器。返回包含 Element 实例和字典的元组。

20.5.3.2. 元素对象

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

元素类。此类定义了Element接口,并提供了此接口的参考实现。

元素名称,属性名称和属性值可以是bytestrings或Unicode字符串。 tag 是元素名称。 attrib 是一个可选的字典,包含元素属性。 extra 包含作为关键字参数给出的其他属性。

tag

一个字符串,用于标识此元素表示的数据类型(换句话说,元素类型)。

text
tail

这些属性可用于保存与元素关联的其他数据。它们的值通常是字符串,但可以是任何特定于应用程序的对象。如果元素是从XML文件创建的,则 text 属性保存元素的开始标签与其第一个子标签或结束标签(或 None)之间的文本,而 tail 属性保存元素的结束标签和下一个标签之间的文本,或 None。对于XML数据

<a><b>1<c>2<d/>3</c></b>4</a>

a 元件具有针对 texttail 属性的 Noneb 元件具有 text "1"tail "4"c 元件具有 text "2"tail None,并且 d 元件具有 text Nonetail "3"

要收集元素的内部文本,请参阅 itertext(),例如 "".join(element.itertext())

应用程序可以在这些属性中存储任意对象。

attrib

包含元素属性的字典。请注意,虽然 attrib 值总是一个真正可变的Python字典,但是ElementTree实现可以选择使用另一个内部表示,并且只有在有人请求时才创建字典。要利用这样的实现,尽可能使用下面的字典方法。

以下类似字典的方法适用于元素属性。

clear()

重置元素。此函数删除所有子元素,清除所有属性,并将文本和尾属性设置为 None

get(key, default=None)

获取名为 key 的元素属性。

返回属性值,如果未找到属性,则返回 default

items()

将元素属性返回为(名称,值)对的序列。属性以任意顺序返回。

keys()

将元素属性名称作为列表返回。以任意顺序返回名称。

set(key, value)

将元素上的属性 key 设置为 value

以下方法适用于元素的子代(子元素)。

append(subelement)

将元素 subelement 添加到此元素的内部子元素列表的末尾。如果 subelement 不是 Element,则提高 TypeError

extend(subelements)

从具有零个或多个元素的序列对象附加 subelements。如果子元素不是 Element,则提高 TypeError

3.2 新版功能.

find(match, namespaces=None)

找到匹配 match 的第一个子元素。 match 可以是标签名称或 路径。返回元素实例或 Nonenamespaces 是从命名空间前缀到全名的可选映射。

findall(match, namespaces=None)

通过标记名称或 路径 查找所有匹配的子元素。返回包含文档顺序中所有匹配元素的列表。 namespaces 是从命名空间前缀到全名的可选映射。

findtext(match, default=None, namespaces=None)

查找与 match 匹配的第一个子元素的文本。 match 可以是标签名称或 路径。返回第一个匹配元素的文本内容,如果没有找到元素,则返回 default。注意,如果匹配元素没有文本内容,则返回空字符串。 namespaces 是从命名空间前缀到全名的可选映射。

getchildren()

3.2 版后已移除: 使用 list(elem) 或迭代。

getiterator(tag=None)

3.2 版后已移除: 使用方法 Element.iter()

insert(index, subelement)

在此元素的给定位置插入 subelement。如果 subelement 不是 Element,则提高 TypeError

iter(tag=None)

创建一个以当前元素为根的树 iterator。迭代器以文档(深度优先)顺序遍历该元素及其下面的所有元素。如果 tag 不是 None'*',则只有标签等于 tag 的元素从迭代器返回。如果在迭代期间修改树结构,则结果是未定义的。

3.2 新版功能.

iterfind(match, namespaces=None)

通过标记名称或 路径 查找所有匹配的子元素。返回一个可迭代的产生文档顺序中的所有匹配元素。 namespaces 是从命名空间前缀到全名的可选映射。

3.2 新版功能.

itertext()

创建文本迭代器。迭代器按文档顺序循环遍历该元素和所有子元素,并返回所有内部文本。

3.2 新版功能.

makeelement(tag, attrib)

创建与此元素相同类型的新元素对象。不要调用此方法,请改用 SubElement() 工厂函数。

remove(subelement)

从元素中删除 subelement。与find *方法不同,此方法根据实例标识比较元素,而不是标记值或内容。

Element 对象还支持使用子元素的以下序列类型方法:__delitem__()__getitem__()__setitem__()__len__()

注意:没有子元素的元素将被测试为 False。此行为将在以后的版本中更改。使用特定的 len(elem)elem is None 测试。

element = root.find('foo')

if not element:  # careful!
    print("element not found, or element has no subelements")

if element is None:
    print("element not found")

20.5.3.3. ElementTree对象

class xml.etree.ElementTree.ElementTree(element=None, file=None)

ElementTree包装类。此类表示整个元素层次结构,并为标准XML中的序列化添加了一些额外的支持。

element 是根元素。使用XML file 的内容(如果给定)初始化树。

_setroot(element)

替换此树的根元素。这将丢弃树的当前内容,并用给定的元素替换它。小心使用。 element 是一个元素实例。

find(match, namespaces=None)

Element.find() 相同,从树的根开始。

findall(match, namespaces=None)

Element.findall() 相同,从树的根开始。

findtext(match, default=None, namespaces=None)

Element.findtext() 相同,从树的根开始。

getiterator(tag=None)

3.2 版后已移除: 使用方法 ElementTree.iter()

getroot()

返回此树的根元素。

iter(tag=None)

为根元素创建并返回一个树迭代器。迭代器按照节顺序在该树中的所有元素上循环。 tag 是要查找的标签(默认是返回所有元素)。

iterfind(match, namespaces=None)

Element.iterfind() 相同,从树的根开始。

3.2 新版功能.

parse(source, parser=None)

将外部XML部分加载到此元素树中。 source 是文件名或 file objectparser 是一个可选的解析器实例。如果没有给出,则使用标准 XMLParser 解析器。返回段根元素。

write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml", *, short_empty_elements=True)

将元素树写入文件,如XML。 file 是文件名,或者是打开的 file objectencoding [1] 是输出编码(默认为US-ASCII)。 xml_declaration 控制是否应将XML声明添加到文件。使用 False 从不,True 为始终,None 仅当不是US-ASCII或UTF-8或Unicode(默认为 None)。 default_namespace 设置默认的XML命名空间(对于“xmlns”)。 method"xml""html""text" (默认是 "xml")。仅限关键字的 short_empty_elements 参数控制不包含任何内容的元素的格式。如果 True (默认),它们作为单个自封闭标签发出,否则它们作为一对开始/结束标签发出。

输出是字符串(str)或二进制(bytes)。这由 encoding 参数控制。如果 encoding"unicode",则输出是字符串;否则,它是二进制。注意,如果它是开放的 file object,这可能与 file 的类型冲突;请确保您不尝试将字符串写入二进制流,反之亦然。

3.4 新版功能: short_empty_elements 参数。

这是将要处理的XML文件:

<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>Moved to <a href="http://example.org/">example.org</a>
        or <a href="http://example.com/">example.com</a>.</p>
    </body>
</html>

更改第一段中每个链接的属性“目标”的示例:

>>> from xml.etree.ElementTree import ElementTree
>>> tree = ElementTree()
>>> tree.parse("index.xhtml")
<Element 'html' at 0xb77e6fac>
>>> p = tree.find("body/p")     # Finds first occurrence of tag p in body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a"))   # Returns list of all links
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links:             # Iterates through all found links
...     i.attrib["target"] = "blank"
>>> tree.write("output.xhtml")

20.5.3.4. QName对象

class xml.etree.ElementTree.QName(text_or_uri, tag=None)

QName包装器。这可以用于包装QName属性值,以便在输出上获得正确的命名空间处理。 text_or_uri 是一个包含QName值的字符串,格式为{uri} local,或者如果给定tag参数,则为QName的URI部分。如果给出 tag,则第一个参数被解释为URI,并且该参数被解释为本地名称。 QName 实例不透明。

20.5.3.5. TreeBuilder对象

class xml.etree.ElementTree.TreeBuilder(element_factory=None)

通用元素结构构建器。此构建器将开始,数据和结束方法调用的顺序转换为格式良好的元素结构。您可以使用此类使用自定义XML解析器或一些其他类似XML格式的解析器来构建元素结构。 element_factory,当给定时,必须是可调用的接受两个位置参数:标签和属性的dict。它期望返回一个新的元素实例。

close()

刷新构建器缓冲区,并返回顶级文档元素。返回 Element 实例。

data(data)

向当前元素添加文本。 data 是一个字符串。这应该是字节表或Unicode字符串。

end(tag)

关闭当前元素。 tag 是元素名称。返回closed元素。

start(tag, attrs)

打开一个新元素。 tag 是元素名称。 attrs 是包含元素属性的字典。返回打开的元素。

此外,自定义 TreeBuilder 对象可以提供以下方法:

doctype(name, pubid, system)

处理一个doctype声明。 name 是doctype名称。 pubid 是公共标识符。 system 是系统标识符。此方法不存在于默认 TreeBuilder 类上。

3.2 新版功能.

20.5.3.6. XMLParser对象

class xml.etree.ElementTree.XMLParser(html=0, target=None, encoding=None)

这个类是模块的低级构建块。它使用 xml.parsers.expat 进行高效的基于事件的XML解析。它可以使用 feed() 方法递增地提供XML数据,并且通过调用 target 对象上的回调将解析事件转换为推送API。如果省略 target,则使用标准 TreeBuilderhtml 参数历史上用于向后兼容性,现在已被弃用。如果给定 encoding [1],该值将覆盖XML文件中指定的编码。

3.4 版后已移除: html 参数。剩余的参数应通过关键字传递,以准备删除 html 参数。

close()

完成将数据提供给解析器。返回调用构造过程中传递的 targetclose() 方法的结果;默认情况下,这是toplevel文档元素。

doctype(name, pubid, system)

3.2 版后已移除: 在自定义TreeBuilder目标上定义 TreeBuilder.doctype() 方法。

feed(data)

将数据提供给解析器。 data 是编码数据。

XMLParser.feed() 为每个开始标记调用 targetstart(tag, attrs_dict) 方法,为每个结束标记调用其 end(tag) 方法,并通过方法 data(data) 处理数据。 XMLParser.close() 调用 target 的方法 close()XMLParser 不仅可用于构建树结构。这是计算XML文件的最大深度的示例:

>>> from xml.etree.ElementTree import XMLParser
>>> class MaxDepth:                     # The target object of the parser
...     maxDepth = 0
...     depth = 0
...     def start(self, tag, attrib):   # Called for each opening tag.
...         self.depth += 1
...         if self.depth > self.maxDepth:
...             self.maxDepth = self.depth
...     def end(self, tag):             # Called for each closing tag.
...         self.depth -= 1
...     def data(self, data):
...         pass            # We do not need to do anything with data.
...     def close(self):    # Called when all data has been parsed.
...         return self.maxDepth
...
>>> target = MaxDepth()
>>> parser = XMLParser(target=target)
>>> exampleXml = """
... <a>
...   <b>
...   </b>
...   <b>
...     <c>
...       <d>
...       </d>
...     </c>
...   </b>
... </a>"""
>>> parser.feed(exampleXml)
>>> parser.close()
4

20.5.3.7. XMLPullParser对象

class xml.etree.ElementTree.XMLPullParser(events=None)

一个适用于非阻塞应用程序的拉解析器。它的输入端API类似于 XMLParser,但是 XMLPullParser 不是将调用推送到回调目标,而是收集解析事件的内部列表,并让用户从中读取它。 events 是要报告的事件序列。支持的事件是字符串 "start""end""start-ns""end-ns" (“ns”事件用于获取详细的命名空间信息)。如果省略 events,则仅报告 "end" 事件。

feed(data)

将给定字节数据馈送到解析器。

close()

向解析器发信号通知数据流已终止。与 XMLParser.close() 不同,此方法总是返回 None。当解析器关闭时尚未检索的任何事件仍然可以使用 read_events() 读取。

read_events()

对馈送到解析器的数据中遇到的事件返回一个迭代器。迭代器产生 (event, elem) 对,其中 event 是表示事件类型(例如 "end")的字符串,elem 是遇到的 Element 对象。

在先前对 read_events() 的调用中提供的事件将不会再次产生。仅当从迭代器中检索到事件时才从内部队列中消耗事件,因此从 read_events() 获取的迭代器上并行迭代的多个读取器将具有不可预测的结果。

注解

XMLPullParser 只保证当它发出一个“开始”事件时它已经看到起始标签的“>”字符,因此定义了属性,但是文本和尾部属性的内容在该点是未定义的。这同样适用于元素儿;它们可以存在或可以不存在。

如果您需要一个完全填充的元素,请查找“结束”事件。

3.4 新版功能.

20.5.3.8. 例外

class xml.etree.ElementTree.ParseError

XML解析错误,由解析失败时此模块中的各种解析方法引发。此异常的实例的字符串表示将包含一个用户友好的错误消息。此外,它将具有以下属性可用:

code

expat解析器的数字错误代码。有关错误代码及其含义的列表,请参阅 xml.parsers.expat 的文档。

position

linecolumn 数字的元组,指定错误发生的位置。

脚注

[1]

XML输出中包含的编码字符串应符合相应的标准。例如,“UTF-8”有效,但“UTF8”不是。见 https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDeclhttps://www.iana.org/assignments/character-sets/character-sets.xhtml