xml.etree.ElementTree ---元素树XML API

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


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

在 3.3 版更改: 此模块将在任何可用的情况下使用快速实现。

3.3 版后已移除: 这个 xml.etree.cElementTree 模块已弃用。

警告

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

教程

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

XML树和元素

XML是一种固有的分层数据格式,最自然的表示方法是使用树。 ET 为此有两个类- ElementTree 将整个XML文档表示为树,并且 Element 表示此树中的单个节点。与整个文档的交互(文件的读写)通常在 ElementTree 水平。与单个XML元素及其子元素的交互是在 Element 水平。

解析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从字符串直接解析为 Element ,它是解析树的根元素。其他解析函数可能会创建 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 构造函数。

拉api进行非阻塞解析

这个模块提供的大多数解析函数都要求在返回任何结果之前立即读取整个文档。可以使用 XMLParser 并将数据以增量方式输入到其中,但它是一个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文档,并且不希望将其全部保存在内存中时,它可能非常有用。

寻找有趣的元素

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() 找到 第一 带有特定标签的子项,以及 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 .

修改XML文件

ElementTree 提供一种构建XML文档并将其写入文件的简单方法。这个 ElementTree.write() 方法就是为了这个目的。

一旦创建,一个 Element 对象可以通过直接更改其字段(例如 Element.text )添加和修改属性 (Element.set() 方法),以及添加新子项(例如 Element.append()

假设我们想在每个国家的排名中加一个,然后加一个 updated rank元素的属性:

>>> 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'):
...     # using root.findall() to avoid removal during traversal
...     rank = int(country.find('rank').text)
...     if rank > 50:
...         root.remove(country)
...
>>> tree.write('output.xml')

请注意,迭代时的并发修改可能会导致问题,就像迭代和修改Python列表或字典时一样。因此,该示例首先使用 root.findall() ,然后才遍历匹配列表。

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

生成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>

使用命名空间分析XML

如果XML输入有 namespaces _表单中带有前缀的标记和属性 prefix:sometag 扩展到 {{uri}}sometag 何处 前缀 替换为完整的 URI . 此外,如果有 default namespace _这个完整的URI被预先附加到所有的非前缀标记上。

下面是一个XML示例,它包含两个命名空间,一个带有前缀“虚构的”,另一个用作默认命名空间:

<?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() ::

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

其他资源

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

XPath支持

此模块对 XPath expressions 用于定位树中的元素。目标是支持缩写语法的一小部分;完整的XPath引擎不在模块的范围内。

例子

下面是一个示例,演示了模块的一些XPath功能。我们将使用 countrydata 来自的XML文档 Parsing 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]")

对于带有名称空间的XML,请使用通常限定的 {{namespace}}tag 符号:

# All dublin-core "title" tags in the document
root.findall(".//{http://purl.org/dc/elements/1.1/}title")

支持的xpath语法

句法

意义

tag

选择具有给定标记的所有子元素。例如, spam 选择所有名为的子元素 spamspam/egg 选择所有名为的孙子 egg 在所有的孩子中 spam . {{namespace}}* 选择给定命名空间中的所有标记, {{*}}spam 选择名为的标记 spam 在任何(或没有)命名空间中,以及 {{}}* 仅选择不在命名空间中的标记。

在 3.8 版更改: 增加了对星形通配符的支持。

*

选择所有子元素,包括注释和处理说明。例如, */egg 选择所有名为的孙子 egg .

.

选择当前节点。这在路径的开头非常有用,表明它是一个相对路径。

//

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

..

选择父元素。返回 None 如果路径试图到达开始元素(元素 find 被叫上)。

[@attrib]

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

[@attrib='value']

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

[@attrib!='value']

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

3.10 新版功能.

[tag]

选择具有名为的子级的所有元素 tag . 只支持直接子项。

[.='text']

选择其完整文本内容(包括子体)等于给定内容的所有元素 text .

3.7 新版功能.

[.!='text']

选择其完整文本内容(包括子体)不等于给定 text

3.10 新版功能.

[tag='text']

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

[tag!='text']

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

3.10 新版功能.

[position]

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

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

参考文献

功能

xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)

C14N 2.0 转换函数。

规范化是一种使XML输出正常化的方法,允许逐字节比较和数字签名。它减少了XML序列化程序的自由度,而生成了更受约束的XML表示。主要限制包括名称空间声明的位置、属性的顺序和可忽略的空白。

此函数接受XML数据字符串( xml_data )或文件路径或类似文件的对象( from_file )作为输入,将其转换为规范形式,并使用 out 文件(-like)对象(如果提供),或者将其作为文本字符串返回(如果不提供)。输出文件接收文本,而不是字节。因此应在文本模式下打开 utf-8 编码。

典型用途:

xml_data = "<root>...</root>"
print(canonicalize(xml_data))

with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
    canonicalize(xml_data, out=out_file)

with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
    canonicalize(from_file="inputfile.xml", out=out_file)

配置 选项 如下:

  • with_comments :设置为true以包含注释(默认值:false)

  • strip_text :设置为“真”可去除文本内容前后的空白

    (默认值:假)

  • rewrite_prefixes :设置为true将命名空间前缀替换为“n数字”

    (默认值:假)

  • qname_aware_tags :一组可识别QName的标记名,其中前缀

    应在文本内容中替换(默认:空)

  • qname_aware_attrs :一组可识别QName的属性名,其中前缀

    应在文本内容中替换(默认:空)

  • exclude_attrs :一组不应序列化的属性名

  • exclude_tags :一组不应序列化的标记名

在上面的选项列表中,“集合”指的是任何集合或字符串的ITerable,不需要排序。

3.8 新版功能.

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

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

注意 XMLParser 跳过输入中的注释,而不是为它们创建注释对象。安 ElementTree 仅当注释节点已使用 Element 方法。

xml.etree.ElementTree.dump(elem)

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

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

elem 是元素树或单个元素。

在 3.8 版更改: 这个 dump() 函数现在保留用户指定的属性顺序。

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

从字符串常量分析XML节。等同于 XML() . text 是包含XML数据的字符串。 语法分析器 是可选的分析程序实例。如果没有给出,标准 XMLParser 使用分析器。返回 Element 实例。

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

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

3.2 新版功能.

xml.etree.ElementTree.indent(tree, space='  ', level=0)

将空白追加到子树以直观地缩进树。这可以用来生成打印良好的XML输出。 tree 可以是元素或元素树。 空间 是将为每个缩进级别插入的空白字符串,默认为两个空格字符。对于缩进已缩进的树中的部分子树,将初始缩进级别传递为 水平 .

3.9 新版功能.

xml.etree.ElementTree.iselement(element)

检查对象是否是有效的元素对象。 要素 是元素实例。返回 True 如果这是元素对象。

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

以增量方式将XML部分解析为元素树,并向用户报告所发生的事情。 来源 是文件名或 file object 包含XML数据。 事件 是要报告的事件序列。支持的事件是字符串 "start""end""comment""pi""start-ns""end-ns" (使用“ns”事件获取详细的命名空间信息)。如果 事件 仅省略 "end" 报告事件。 语法分析器 是可选的分析程序实例。如果没有给出,标准 XMLParser 使用解析器。 语法分析器 必须是的子类 XMLParser 只能使用默认值 TreeBuilder 作为目标。返回一个 iterator 提供 (event, elem) 对。

注意,同时 iterparse() 以增量方式构建树,它发出阻塞读取的问题 source (或者它命名的文件)。因此,它不适用于无法进行阻塞读取的应用程序。有关完全非阻塞解析,请参见 XMLPullParser .

注解

iterparse() 只保证它在发出“start”事件时看到了开始标记的“>”字符,因此定义了属性,但此时未定义文本和尾部属性的内容。这同样适用于元素子元素;它们可能存在,也可能不存在。

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

3.4 版后已移除: 这个 语法分析器 参数。

在 3.8 版更改: 这个 commentpi 事件已添加。

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

将XML节解析为元素树。 source 是包含XML数据的文件名或文件对象。 语法分析器 是可选的分析程序实例。如果没有给出,标准 XMLParser 使用分析器。返回一个 ElementTree 实例。

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

PI元件厂。此factory函数创建一个特殊元素,该元素将被序列化为XML处理指令。 目标 是包含pi目标的字符串。 text 如果给定,则是包含PI内容的字符串。返回表示处理指令的元素实例。

注意 XMLParser 跳过输入中的处理指令,而不是为它们创建注释对象。安 ElementTree 仅当处理指令节点已使用 Element 方法。

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

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

3.2 新版功能.

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

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

元素名、属性名和属性值可以是字节字符串或Unicode字符串。 起源 是父元素。 tag 是子元素名称。 阿特里布 是可选字典,包含元素属性。 额外的 包含作为关键字参数提供的其他属性。返回元素实例。

xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

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

3.4 新版功能: 这个 short_empty_elements 参数。

3.8 新版功能: 这个 xml_declarationdefault_namespace 参数。

在 3.8 版更改: 这个 tostring() 函数现在保留用户指定的属性顺序。

xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

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

3.2 新版功能.

3.4 新版功能: 这个 short_empty_elements 参数。

3.8 新版功能: 这个 xml_declarationdefault_namespace 参数。

在 3.8 版更改: 这个 tostringlist() 函数现在保留用户指定的属性顺序。

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

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

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

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

XInclude支持

此模块对 XInclude directives ,通过 xml.etree.ElementInclude 助手模块。此模块可用于根据树中的信息将子树和文本字符串插入元素树中。

例子

下面的示例演示了XInclude模块的使用。要在当前文档中包含XML文档,请使用 {{http://www.w3.org/2001/XInclude}}include 元素并设置 解析 属性到 "xml" ,并使用 href 属性指定要包含的文档。

<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="source.xml" parse="xml" />
</document>

默认情况下, href 属性被视为文件名。可以使用自定义加载程序重写此行为。还要注意,标准帮助程序不支持XPointer语法。

若要处理此文件,请照常加载,并将根元素传递给 xml.etree.ElementTree 模块:

from xml.etree import ElementTree, ElementInclude

tree = ElementTree.parse("document.xml")
root = tree.getroot()

ElementInclude.include(root)

ElementInclude模块替换 {{http://www.w3.org/2001/XInclude}}include 元素的根元素 source.xml 文件。结果可能是这样的:

<document xmlns:xi="http://www.w3.org/2001/XInclude">
  <para>This is a paragraph.</para>
</document>

如果 解析 属性被省略,它默认为“xml”。需要使用href属性。

要包含文本文档,请使用 {{http://www.w3.org/2001/XInclude}}include 元素,并设置 解析 “文本”属性:

<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
  Copyright (c) <xi:include href="year.txt" parse="text" />.
</document>

结果可能类似于:

<document xmlns:xi="http://www.w3.org/2001/XInclude">
  Copyright (c) 2003.
</document>

参考文献

功能

xml.etree.ElementInclude.default_loader(href, parse, encoding=None)

默认加载程序。此默认加载程序从磁盘读取包含的资源。 href 是一个URL。 解析 用于解析模式“xml”或“text”。 编码 是可选的文本编码。如果没有给出,编码是 utf-8 . 返回展开的资源。如果解析模式是 "xml" ,这是ElementTree实例。如果解析模式是“文本”,则这是一个Unicode字符串。如果加载程序失败,它可以返回None或引发异常。

xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)

此函数用于扩展XInclude指令。 elem 是根元素。 加载器 是可选的资源加载程序。如果省略,则默认为 default_loader() . 如果给定,它应该是一个实现与 default_loader() . base_url 是原始文件的基URL,用于解析相对包含文件引用。 max_depth 是递归包含的最大数目。限制以减少恶意内容爆炸的风险。传递负值以禁用限制。

返回展开的资源。如果解析模式是 "xml" ,这是ElementTree实例。如果解析模式是“文本”,则这是一个Unicode字符串。如果加载程序失败,它可以返回None或引发异常。

3.9 新版功能: 这个 base_urlmax_depth 参数。

元素对象

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

元素类。此类定义元素接口,并提供此接口的引用实现。

元素名、属性名和属性值可以是字节字符串或Unicode字符串。 tag 是元素名。 阿特里布 是可选字典,包含元素属性。 额外的 包含作为关键字参数提供的其他属性。

tag

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

text
tail

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

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

这个 a 元素具有 None 对于两者 texttail 属性 b 元素具有 text "1"tail "4" , the c 元素具有 text "2"tail Noned 元素具有 text Nonetail "3" .

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

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

attrib

包含元素属性的字典。注意,当 阿特里布 值始终是一个真正可变的python字典,elementtree实现可以选择使用另一个内部表示,并且只有在有人要求时才创建字典。要利用这种实现,请尽可能使用下面的字典方法。

以下类似字典的方法处理元素属性。

clear()

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

get(key, default=None)

获取名为的元素属性 key .

返回属性值,或 default 如果找不到属性。

items()

以(名称、值)对的顺序返回元素属性。属性以任意顺序返回。

keys()

以列表形式返回元素属性名。名称以任意顺序返回。

set(key, value)

设置属性 key 在元素上 value .

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

append(subelement)

添加元素 子元素 到该元素内部子元素列表的末尾。引发 TypeError 如果 子元素 不是一个 Element .

extend(subelements)

追加 子元素 来自具有零个或多个元素的序列对象。引发 TypeError 如果子元素不是 Element .

3.2 新版功能.

find(match, namespaces=None)

查找匹配的第一个子元素 比赛 . 比赛 可能是标记名或 path . 返回元素实例或 None . 命名空间 是从命名空间前缀到全名的可选映射。通过 '' 作为前缀,将表达式中所有未准备的标记名移动到给定的命名空间中。

findall(match, namespaces=None)

按标记名或查找所有匹配的子元素 path . 返回按文档顺序包含所有匹配元素的列表。 命名空间 是从命名空间前缀到全名的可选映射。通过 '' 作为前缀,将表达式中所有未准备的标记名移动到给定的命名空间中。

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

查找匹配的第一个子元素的文本 比赛 . 比赛 可能是标记名或 path .返回第一个匹配元素的文本内容,或者 违约 如果没有找到元素。注意,如果匹配元素没有文本内容,则返回空字符串。 命名空间 是从命名空间前缀到全名的可选映射。通过 '' 作为前缀,将表达式中所有未准备的标记名移动到给定的命名空间中。

insert(index, subelement)

插入物 子元素 在元素的给定位置。引发 TypeError 如果 子元素 不是一个 Element .

iter(tag=None)

创建树 iterator 以当前元素为根。迭代器按文档(深度优先)顺序迭代此元素及其下面的所有元素。如果 tag 不是 None'*' ,仅限标记等于的元素 tag 从迭代器返回。如果在迭代过程中修改了树结构,则结果是未定义的。

3.2 新版功能.

iterfind(match, namespaces=None)

按标记名或查找所有匹配的子元素 path . 返回一个ITerable,按文档顺序生成所有匹配的元素。 命名空间 是从命名空间前缀到全名的可选映射。

3.2 新版功能.

itertext()

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

3.2 新版功能.

makeelement(tag, attrib)

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

remove(subelement)

移除 子元素 从元素。不像发现 * 方法此方法基于实例标识比较元素,而不是基于标记值或内容。

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

在Python3.8之前,通过按属性名称排序,人为地使元素的XML属性的序列化顺序可预测。基于现在保证的dict排序,在python 3.8中删除了这种任意的重新排序,以保留最初由用户代码解析或创建属性的顺序。

通常,用户代码不应依赖于属性的特定顺序,因为 XML Information Set 从传递信息中显式排除属性顺序。代码应该准备好处理输入的任何排序。在需要确定性XML输出的情况下,例如,对于加密签名或测试数据集,规范化序列化可用于 canonicalize() 功能。

如果规范输出不适用,但输出上仍需要特定的属性顺序,那么代码应该以所需的顺序直接创建属性,以避免代码读卡器的感知不匹配。如果很难实现这一点,可以在序列化之前应用如下配方,以独立于元素创建来强制执行订单:

def reorder_attributes(root):
    for el in root.iter():
        attrib = el.attrib
        if len(attrib) > 1:
            # adjust attribute order, e.g. by sorting
            attribs = sorted(attrib.items())
            attrib.clear()
            attrib.update(attribs)

元素树对象

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

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

要素 是根元素。树是用XML的内容初始化的 file 如果给出的话。

_setroot(element)

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

find(match, namespaces=None)

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

findall(match, namespaces=None)

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

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

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

getroot()

返回此树的根元素。

iter(tag=None)

为根元素创建并返回树迭代器。迭代器按节顺序循环此树中的所有元素。 tag 是要查找的标记(默认为返回所有元素)。

iterfind(match, namespaces=None)

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

3.2 新版功能.

parse(source, parser=None)

将外部XML部分加载到此元素树中。 source 是文件名还是 file object . 语法分析器 是可选的分析程序实例。如果没有给出,标准 XMLParser 使用分析器。返回节根元素。

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

将元素树以XML形式写入文件。 file 是文件名,或 file object 开放写作。 encoding 1 是输出编码(默认为US-ASCII)。 xml_declaration 控制是否应将XML声明添加到文件中。使用 False 永远, True 永远, None 仅当不是US-ASCII或UTF-8或Unicode时(默认为 Nonedefault_namespace 设置默认的XML命名空间(对于“xmlns”)。 方法 要么是 "xml""html""text" (默认为 "xml" )仅关键字 short_empty_elements 参数控制不包含内容的元素的格式。如果 True (默认情况下),它们作为单个自关闭标记发出,否则它们作为一对开始/结束标记发出。

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

3.4 新版功能: 这个 short_empty_elements 参数。

在 3.8 版更改: 这个 write() 方法现在保留用户指定的属性顺序。

这是要操作的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>

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

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

QNoT对象

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

QName封装。这可用于封装qname属性值,以便对输出进行正确的命名空间处理。 text_or_uri 是包含qname值的字符串,格式为uri local,或者,如果给定了标记参数,则为qname的uri部分。如果 tag 如果给定,则第一个参数将解释为URI,而此参数将解释为本地名称。 QName 实例是不透明的。

TreeBuilder对象

class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)

通用元素结构生成器。此生成器将start、data、end、comment和pi方法调用的序列转换为格式良好的元素结构。您可以使用这个类使用定制的XML解析器或其他类似XML格式的解析器来构建元素结构。

element_factory 如果给定,则必须是可调用的,接受两个位置参数:标记和属性dict。它将返回一个新的元素实例。

这个 comment_factorypi_factory 函数在给定时的行为应类似于 Comment()ProcessingInstruction() 用于创建注释和处理指令的函数。如果不提供,将使用默认工厂。什么时候? insert_comments 和/或 insert_pis 为真,如果注释/pis出现在根元素中(但不在根元素之外),则它们将插入到树中。

close()

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

data(data)

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

end(tag)

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

start(tag, attrs)

打开新元素。 tag 是元素名。 阿特斯 是包含元素属性的字典。返回打开的元素。

comment(text)

使用给定的 text . 如果 insert_comments 是的,这也会将其添加到树中。

3.8 新版功能.

pi(target, text)

使用给定的 目标 姓名和 text . 如果 insert_pis 是的,这也会将其添加到树中。

3.8 新版功能.

另外,一个习俗 TreeBuilder 对象可以提供以下方法:

doctype(name, pubid, system)

处理doctype声明。 name 是doctype名称。 普比德 是公共标识符。 系统 是系统标识符。默认情况下不存在此方法 TreeBuilder 类。

3.2 新版功能.

start_ns(prefix, uri)

每当分析器遇到新的命名空间声明时,在 start() 为定义它的开始元素回调。 前缀'' 对于默认名称空间和声明的名称空间前缀名称。 uri 是命名空间URI。

3.8 新版功能.

end_ns(prefix)

是在 end() 声明命名空间前缀映射的元素的回调,其名称为 前缀 那超出了范围。

3.8 新版功能.

class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None)

A C14N 2.0 作家。参数与 canonicalize() 功能。此类不构建树,而是使用 功能。

3.8 新版功能.

XmlParser对象

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

这个类是模块的低级构造块。它使用 xml.parsers.expat 为了高效、基于事件的XML解析。它可以用 feed() 方法和解析事件被转换为push api-通过调用 目标 对象。如果 目标 省略,标准 TreeBuilder 使用。如果 encoding 1 如果给定,该值将覆盖XML文件中指定的编码。

在 3.8 版更改: 参数现在是 keyword-only . 这个 html 不再支持参数。

close()

向分析器提供数据结束。返回调用 close() 方法 目标 在构造期间传递;默认情况下,这是顶级文档元素。

feed(data)

向分析器提供数据。 data 是编码数据。

XMLParser.feed() 电话 目标start(tag, attrs_dict) 每个开始标记的方法,其 end(tag) 每个结束标记的方法,并通过方法处理数据 data(data) . 有关进一步支持的回调方法,请参见 TreeBuilder 班级。 XMLParser.close() 电话 目标 方法 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

XmlPullParser对象

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

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

feed(data)

向分析器提供给定的字节数据。

close()

向解析器发出终止数据流的信号。不像 XMLParser.close() ,此方法始终返回 None . 当解析器关闭时,任何尚未检索到的事件仍然可以用 read_events() .

read_events()

返回一个迭代器,该迭代器将返回给解析器的数据中遇到的事件。迭代器生成 (event, elem) 对,在哪里 事件 是表示事件类型的字符串(例如 "end"elem 是否遇到 Element 对象或其他上下文值,如下所示。

  • startend :当前元素。

  • commentpi :当前注释/处理指令

  • start-ns :一个元组 (prefix, uri) 命名声明的命名空间映射。

  • end-ns: None (这可能在将来的版本中更改)

上一次调用中提供的事件 read_events() 不会再屈服了。只有从迭代器中检索到事件时,才会从内部队列中使用这些事件,因此多个读卡器通过迭代器并行迭代 read_events() 会有不可预知的结果。

注解

XMLPullParser 只保证它在发出“start”事件时看到了开始标记的“>”字符,因此定义了属性,但此时未定义文本和尾部属性的内容。这同样适用于元素子元素;它们可能存在,也可能不存在。

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

3.4 新版功能.

在 3.8 版更改: 这个 commentpi 事件已添加。

例外情况

class xml.etree.ElementTree.ParseError

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

code

来自expat分析器的数字错误代码。参见以下文件: xml.parsers.expat 错误代码及其含义列表。

position

一个元组 line 数字,指定错误发生的位置。

脚注

1(1,2,3,4)

XML输出中包含的编码字符串应符合适当的标准。例如,“utf-8”有效,但“utf8”无效。请参阅https://www.w3.org/tr/2006/rec-xml11-20060816/nt encodingdecl和https://www.iana.org/assignments/character-sets/character-sets.xhtml。