xml.etree.ElementTree — ElementTree XML API

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


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

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

Warning

xml.etree.ElementTree模块不能安全防范恶意构建的数据。如果您需要解析不可信或未经身份验证的数据,请参见XML vulnerabilities

Tutorial

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

XML 树和元素

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

Parsing 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>

我们可以pass从文件中读取来导入此数据:

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,而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'}

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

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

Note

并非 XMLImporting 的所有元素finally都将作为已解析树的元素。当前,该模块会跳过 Importing 中的任何 XMLComments,处理指令和文档类型语句。但是,使用此模块的 API 构建的树(而不是从 XML 文本进行解析)可以在其中包含 Comments 和处理指令。它们将在生成 XML 输出时包括在内。可以pass将自定义TreeBuilder实例传递给XMLParser构造函数来访问文档类型语句。

Pull API 用于非阻塞解析

此模块提供的大多数解析Function要求在返回任何结果之前立即读取整个文档。可以使用XMLParser并将数据递增地 Importing 到其中,但是它是一个推 API,它在回调目标上调用方法,该方法太底层了,对于大多数需求而言不方便。有时,用户 true 想要的是能够逐步解析 XML,而不会阻塞操作,同时享受完全构造的Element对象的便利。

最强大的工具是XMLPullParser。它不需要阻塞读取即可获取 XML 数据,而是passXMLPullParser.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 数据,但仍希望具有增量解析Function,请查看iterparse()。当您正在阅读大型 XML 文档并且不想将其完全保存在内存中时,此Function很有用。

寻找有趣的元素

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

pass使用XPath可以更精确地指定要查找的元素。

修改 XML 文件

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

创建Element对象后,可以pass直接更改其字段(例如Element.text),添加和修改属性(Element.set()方法)以及添加新的子对象(例如Element.append())来进行操作。

假设我们要在每个国家/locale 的排名中添加一个,并在 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 的所有国家/locale:

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

构建 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

如果 XMLImporting 具有namespaces,则前缀为prefix:sometag的标记和属性将扩展为{uri}sometag,其中* prefix 将由完整的 URI *代替。另外,如果存在default namespace,则完整的 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

Additional resources

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

XPath support

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

Example

这是一个示例,演示了模块的某些 XPath Function。我们将使用Parsing 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]")

对于具有名称空间的 XML,请使用通常的合格{namespace}tag表示法:

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

支持的 XPath 语法

SyntaxMeaning
tag选择具有给定标签的所有子元素。例如,spam选择所有名为spam的子元素,spam/egg选择所有名为spam的子代中的所有子孙egg{namespace}*选择给定名称空间中的所有标签,{*}spam选择任何(或没有)名称空间中名为spam的标签,{}*仅选择不在名称空间中的标签。


在 3.8 版中进行了更改:添加了对星号通配符的支持。
| * |选择所有子元素,包括 Comments 和处理说明。例如,*/egg选择所有名为egg的孙子。
| . |选择当前节点。 |这在路径的开头最有用,它指示它是相对路径。
| // |选择当前元素下方所有级别上的所有子元素。例如,.//egg选择整个树中的所有egg元素。
| .. |选择父元素。如果路径试图到达起始元素的祖先(元素find被调用),则返回None
| [@attrib] |选择具有给定属性的所有元素。
| [@attrib='value'] |选择给定属性具有给定值的所有元素。该值不能包含引号。
| [tag] |选择所有具有名为tag的子元素的元素。仅支持直子。
| [.='text'] |选择其完整文本内容(包括后代)等于给定的text的所有元素。
3.7 版中的新Function。
| [tag='text'] |选择具有名为tag的子元素的所有元素,其完整文本内容(包括后代)等于给定的text
| [position] |选择位于给定位置的所有元素。 |该位置可以是整数(1 是第一个位置),表达式last()(用于最后一个位置),也可以是相对于最后一个位置的位置(例如last()-1)。

谓词(方括号内的表达式)之前必须带有标签名称,星号或其他谓词。 position谓词必须以标签名称开头。

Reference

Functions

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

规范化是一种以允许逐字节比较和数字签名的方式标准化 XML 输出的方式。它减少了 XML 序列化程序具有的自由度,而是生成了更受约束的 XML 表示形式。主要限制涉及名称空间语句的位置,属性的 Sequences 和可忽略的空白。

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

Typical uses:

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 以包含 Comment(默认值:false)
      • strip_text *:设置为 true 以在文本内容之前和之后去除空格
      • (default: false)
      • rewrite_prefixes *:设置为 true 可以将名称空间前缀替换为“ n{number}”
      • (default: false)
      • qname_aware_tags *:一组 qname 感知标签名称,其中前缀
      • 应替换为文本内容(默认值:空)
      • qname_aware_attrs *:一组 qname 感知属性名称,其中前缀
      • 应替换为文本内容(默认值:空)
    • exclude_attrs *:一组不应序列化的属性名称
    • exclude_tags *:一组不应该序列化的标签名称

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

3.8 版的新Function。

  • xml.etree.ElementTree. Comment(* text = None *)
    • Comments 元素工厂。此工厂函数创建一个特殊元素,该元素将由标准序列化程序序列化为 XMLComments。Comments 字符串可以是字节字符串或 Unicode 字符串。 * text *是包含 Comments 字符串的字符串。返回表示 Comments 的元素实例。

请注意,XMLParser会跳过 Importing 中的 Comments,而不是为其创建 Comments 对象。如果ElementTree仅使用Element方法之一插入到树中,则它们将仅包含 Comments 节点。

  • xml.etree.ElementTree. dump(* elem *)
    • 将元素树或元素结构写入 sys.stdout。此Function应仅用于调试。

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

  • elem *是元素树或单个元素。

在 3.8 版中进行了更改:dump()函数现在保留了用户指定的属性 Sequences。

  • xml.etree.ElementTree. fromstring(* text parser = None *)

    • 从字符串常量解析 XML 部分。与XML()相同。 * text *是包含 XML 数据的字符串。 * parser *是可选的解析器实例。如果未给出,则使用标准XMLParser解析器。返回一个Element实例。
  • xml.etree.ElementTree. fromstringlist(* sequence parser = None *)

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

3.2 版中的新Function。

  • xml.etree.ElementTree. iselement(* element *)

    • 检查对象是否似乎是有效的元素对象。 * element *是一个元素实例。如果这是一个元素对象,则返回True
  • xml.etree.ElementTree. iterparse(* source events = None parser = None *)

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

请注意,虽然iterparse()逐步构建树,但它会在* source *(或其命名的文件)上发出阻止读取的操作。因此,它不适用于无法进行分块读取的应用程序。有关完全无阻塞的分析,请参见XMLPullParser

Note

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

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

从 3.4 版开始不推荐使用:* parser *参数。

在 3.8 版中进行了更改:添加了commentpi事件。

  • 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会跳过 Importing 中的处理指令,而不是为其创建 Comments 对象。如果ElementTree使用Element方法之一插入到树中,则它们仅包含处理指令节点。

  • xml.etree.ElementTree. register_namespace(前缀,* uri *)
    • 注册名称空间前缀。该注册表是全局注册表,并且将删除给定前缀或名称空间 URI 的所有现有 Map。 * prefix *是名称空间前缀。 * uri *是名称空间 uri。如果可能,将使用给定的前缀序列化该命名空间中的标签和属性。

3.2 版中的新Function。

  • xml.etree.ElementTree. SubElement(* parent tag attrib ={} ** extra *)
    • 子工厂。此函数创建一个元素实例,并将其附加到现有元素。

元素名称,属性名称和属性值可以是字节字符串或 Unicode 字符串。 * parent *是父元素。 * tag *是子元素名称。 * attrib *是一个可选的字典,包含元素属性。 * extra *包含其他属性,以关键字参数形式给出。返回一个元素实例。

  • xml.etree.ElementTree. tostring(* element encoding =“ us-ascii” method =“ xml” **,* xml_declaration = None default_namespace = None short_empty_elements = True *)
    • 生成 XML 元素(包括所有子元素)的字符串表示形式。 * element *是Element实例。 * encoding * [1]是输出编码(默认为 US-ASCII)。使用encoding="unicode"生成 Unicode 字符串(否则,将生成一个字节字符串)。 方法"xml""html""text"(默认为"xml")。 * xml_declaration default_namespace short_empty_elements *的含义与ElementTree.write()中的含义相同。返回包含 XML 数据的(可选)编码字符串。

3.4 版中的新Function:* short_empty_elements *参数。

3.8 版中的新Function:* xml_declaration default_namespace *参数。

在 3.8 版中进行了更改:tostring()函数现在保留了用户指定的属性 Sequences。

  • xml.etree.ElementTree. tostringlist(* element encoding =“ us-ascii” method =“ xml” **,* xml_declaration = None default_namespace = None short_empty_elements = True *)
    • 生成 XML 元素(包括所有子元素)的字符串表示形式。 * element *是Element实例。 * encoding * [1]是输出编码(默认为 US-ASCII)。使用encoding="unicode"生成 Unicode 字符串(否则,将生成一个字节字符串)。 方法"xml""html""text"(默认为"xml")。 * xml_declaration default_namespace short_empty_elements *的含义与ElementTree.write()中的含义相同。返回包含 XML 数据的(可选)编码字符串的列表。除了b"".join(tostringlist(element)) == tostring(element)之外,它不保证任何特定的 Sequences。

3.2 版中的新Function。

3.4 版中的新Function:* short_empty_elements *参数。

3.8 版中的新Function:* xml_declaration default_namespace *参数。

在 3.8 版中进行了更改:tostringlist()函数现在保留了用户指定的属性 Sequences。

  • xml.etree.ElementTree. XML(* text parser = None *)

    • 从字符串常量解析 XML 部分。此函数可用于在 Python 代码中嵌入“ XMLLiterals”。 * text *是包含 XML 数据的字符串。 * parser *是可选的解析器实例。如果未给出,则使用标准的XMLParser解析器。返回一个Element实例。
  • xml.etree.ElementTree. XMLID(* text parser = None *)

    • 从字符串常量解析 XML 部分,并返回一个字典,该字典将元素 id:sMap 到元素。 * text *是包含 XML 数据的字符串。 * parser *是可选的解析器实例。如果未给出,则使用标准的XMLParser解析器。返回一个包含Element实例和一个字典的 Tuples。

XInclude support

此模块passxml.etree.ElementInclude帮助器模块为XInclude directives提供了有限的支持。该模块可用于根据树中的信息将子树和文本字符串插入到元素树中。

Example

这是一个演示 XInclude 模块使用的示例。要将 XML 文档包含在当前文档中,请使用{http://www.w3.org/2001/XInclude}include元素并将 parse 属性设置为"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 模块用 source.xml 文档中的根元素替换{http://www.w3.org/2001/XInclude}include元素。结果可能如下所示:

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

如果Ellipsis parse 属性,则默认为“ xml”。 href 属性是必需的。

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

<?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>

Reference

Functions

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

    • 默认加载程序。该默认加载器从磁盘读取包含的资源。 * href *是一个 URL。 * parse *用于“ xml”或“ text”解析模式。 * encoding *是可选的文本编码。如果未给出,则编码为utf-8。返回扩展的资源。如果解析模式为"xml",则这是 ElementTree 实例。如果解析模式为“文本”,则为 Unicode 字符串。如果加载程序失败,它可以返回 None 或引发异常。
  • xml.etree.ElementInclude. include(* elem loader = None *)

    • 此Function扩展了 XInclude 指令。 * elem *是根元素。 * loader *是可选的资源加载器。如果Ellipsis,则默认为default_loader()。如果给定,它应该是可实现与default_loader()相同的接口的可调用对象。返回扩展的资源。如果解析模式为"xml",则这是 ElementTree 实例。如果解析模式为“文本”,则为 Unicode 字符串。如果加载程序失败,它可以返回 None 或引发异常。

Element Objects

    • class * xml.etree.ElementTree. Element(* tag attrib ={} ** extra *)
    • 元素类。此类定义 Element 接口,并提供此接口的参考实现。

元素名称,属性名称和属性值可以是字节字符串或 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 元素的 text tail 属性都具有None b 元素具有 text * "1"和* tail * "4",* c 元素具有 text * "2"和* tail * None, * d 元素具有 text * None和* tail * "3"

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

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

  • attrib
    • 包含元素属性的字典。请注意,虽然* attrib *值始终是 true 的可变 Python 字典,但是 ElementTree 实现可以选择使用其他内部表示形式,并仅在有人要求时创建字典。要利用这些实现,请尽可能使用下面的字典方法。

以下类似字典的方法对元素属性起作用。

  • clear ( )

    • 重置元素。此函数删除所有子元素,清除所有属性,并将 text 和 tail 属性设置为None
  • get(* key default = None *)

    • 获取名为* key *的元素属性。

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

  • items ( )

    • 以(名称,值)对的序列形式返回元素属性。属性以任意 Sequences 返回。
  • keys ( )

    • 返回元素属性名称作为列表。名称以任意 Sequences 返回。
  • set(* key value *)

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

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

  • append(* subelement *)

    • 将元素* subelement 添加到该元素的内部子元素列表的末尾。如果 subelement *不是Element,则引发TypeError
  • extend(子元素)

    • 从具有零个或多个元素的序列对象中追加子元素。如果子元素不是Element,则引发TypeError

3.2 版中的新Function。

  • find(* match namespaces = None *)

    • 查找匹配* match *的第一个子元素。 * match *可以是标签名称或path。返回元素实例或None。 * namespaces *是从名称空间前缀到全名的可选 Map。传递''作为前缀,以将表达式中所有未加前缀的标记名称移入给定的名称空间。
  • findall(* match namespaces = None *)

    • 按标签名称或path查找所有匹配的子元素。返回包含所有按文档 Sequences 匹配的元素的列表。 * namespaces *是从名称空间前缀到全名的可选 Map。传递''作为前缀,以将表达式中所有未加前缀的标记名称移动到给定的名称空间中。
  • findtext(* match default = None namespaces = None *)

    • 查找与* match *匹配的第一个子元素的文本。 * match 可以是标签名称或path。返回第一个匹配元素的文本内容;如果未找到任何元素,则返回 default *。请注意,如果匹配的元素没有文本内容,则返回一个空字符串。 * namespaces *是从名称空间前缀到全名的可选 Map。传递''作为前缀,以将表达式中所有未加前缀的标记名称移动到给定的名称空间中。
  • getchildren ( )

    • 从 3.2 版弃用,将在 3.9 版中删除:使用list(elem)或迭代。
  • getiterator(* tag = None *)

    • 从 3.2 版弃用,将在 3.9 版中删除:改用方法Element.iter()
  • insert(* index subelement *)

    • 在此元素的给定位置插入* subelement 。如果 subelement *不是Element,则引发TypeError
  • iter(* tag = None *)

    • 创建一个以当前元素为根的树iterator。迭代器按照文档(深度优先)的 Sequences 遍历此元素及其下的所有元素。如果* tag 不是None'*',则仅从迭代器返回其标签等于 tag *的元素。如果在迭代过程中修改树结构,则结果不确定。

3.2 版中的新Function。

  • iterfind(* match namespaces = None *)
    • 按标签名称或path查找所有匹配的子元素。返回一个可迭代的结果,按文档 Sequences 生成所有匹配的元素。 * namespaces *是从名称空间前缀到全名的可选 Map。

3.2 版中的新Function。

  • itertext ( )
    • 创建一个文本迭代器。迭代器按文档 Sequences 循环遍历此元素和所有子元素,并返回所有内部文本。

3.2 版中的新Function。

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

在 Python 3.8 之前,pass按属性名称的名称对属性进行排序,可以人为地预测元素的 XML 属性的序列化 Sequences。基于现在保证的字典排序,在 python 3.8 中删除了此任意重新排序,以保留最初由用户代码解析或创建属性的 Sequences。

通常,假定XML 信息集明确将属性 Sequences 从传达信息中排除,则用户代码应尽量不依赖于属性的特定 Sequences。应该准备代码以处理 Importing 的任何 Sequences。在需要确定性 XML 输出的情况下,例如对于密码签名或测试数据集,可使用canonicalize()函数进行规范序列化。

在规范输出不适用但输出仍需要特定属性 Sequences 的情况下,代码应旨在直接按所需 Sequences 创建属性,以避免代码阅 Reader 在感知上不匹配。在难以实现的情况下,可以在序列化之前应用类似于以下的配方来强制执行独立于 Element 创建的 Sequences:

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)

ElementTree Objects

    • class * xml.etree.ElementTree. ElementTree(* element = None file = None *)
    • ElementTree 包装器类。此类表示整个元素层次结构,并为与标准 XML 之间的序列化添加了一些额外的支持。
  • element *是根元素。如果指定了树,则使用 XML * file *的内容进行初始化。
  • _setroot(元素)

    • 替换此树的根元素。这将丢弃树的当前内容,并将其替换为给定的元素。小心使用。 * element *是一个元素实例。
  • find(* match namespaces = None *)

  • findall(* match namespaces = None *)

  • findtext(* match default = None namespaces = None *)

  • getiterator(* tag = None *)

  • getroot ( )

    • 返回此树的根元素。
  • iter(* tag = None *)

    • 为根元素创建并返回一个树迭代器。迭代器按节 Sequences 遍历此树中的所有元素。 * tag *是要查找的标签(默认为返回所有元素)。
  • iterfind(* match namespaces = None *)

3.2 版中的新Function。

  • parse(* source parser = None *)

    • 将外部 XML 节加载到此元素树中。 * source *是文件名或file object。 * parser *是可选的解析器实例。如果未给出,则使用标准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,如果不是 US-ASCII 或 UTF-8 或 Unicode(默认值为None),则只能使用None。 * default_namespace 设置默认的 XML 名称空间(用于“ xmlns”)。 方法"xml""html""text"(默认值为"xml")。仅关键字 short_empty_elements *参数控制不包含任何内容的元素的格式。如果为True(默认值),则将它们作为单个自闭标签发出,否则将作为Pair开始/结束标签发出。

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

3.4 版中的新Function:* short_empty_elements *参数。

在版本 3.8 中进行了更改:write()方法现在保留了用户指定的属性 Sequences。

这是将要处理的 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")

QName Objects

    • class * xml.etree.ElementTree. QName(* text_or_uri tag = None *)
    • QName 包装器。这可以用来包装 QName 属性值,以便对输出进行正确的名称空间处理。 * text_or_uri 是一个包含 QName 值的字符串,格式为\ {} local,或者,如果给出了 tag 参数,则为 QName 的 URI 部分。如果给出 tag *,则第一个参数解释为 URI,而该参数解释为本地名称。 QName个实例不透明。

TreeBuilder Objects

    • class * xml.etree.ElementTree. TreeBuilder(* element_factory = None **,* comment_factory = None pi_factory = None insert_comments = False insert_pis = False *)
    • 通用元素结构生成器。该构建器将开始,数据,结束,Comments 和 pi 方法调用的序列转换为格式良好的元素结构。您可以使用此类使用自定义 XML 解析器或某些其他类似 XML 格式的解析器来构建元素结构。
  • element_factory *(给定时)必须是可调用的,接受两个位置参数:标签和属性字典。预计将返回一个新的元素实例。

如果指定了* comment_factory pi_factory 函数,它们的行为应类似于Comment()ProcessingInstruction()函数,以创建 Comments 和处理指令。如果未给出,将使用默认工厂。当 insert_comments 和/或 insert_pis *为 true 时,如果 Comments/ pis 出现在根元素中(但不在其外部),则将它们插入树中。

  • close ( )

    • 刷新构建器缓冲区,并返回顶级文档元素。返回一个Element实例。
  • data(* data *)

    • 将文本添加到当前元素。 * data *是一个字符串。这应该是字节字符串或 Unicode 字符串。
  • end(标签)

    • 关闭当前元素。 * tag *是元素名称。返回封闭的元素。
  • start(* tag attrs *)

    • 打开一个新元素。 * tag *是元素名称。 * attrs *是包含元素属性的字典。返回打开的元素。
  • comment(文本)

    • 使用给定的* text *创建 Comments。如果insert_comments为 true,则还将其添加到树中。

3.8 版的新Function。

  • pi(* target text *)
    • 使用给定的* target 名称和 text *创建 Comments。如果insert_pis为 true,则还将其添加到树中。

3.8 版的新Function。

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

  • doctype(* name pubid system *)
    • 处理文档类型语句。 * name *是文档类型名称。 * pubid *是公共标识符。 * system *是系统标识符。默认的TreeBuilder类不存在此方法。

3.2 版中的新Function。

  • start_ns(前缀,* uri *)
    • 每当解析器在定义它的开始元素的start()回调之前遇到新的名称空间语句时,都会调用。默认名称空间的* prefix *为'',否则为语句的名称空间前缀名称。 * uri *是名称空间 URI。

3.8 版的新Function。

  • end_ns(前缀)
    • 在语句了名称空间前缀 Map 的元素的end()回调之后被调用,其名称带有超出范围的* prefix *。

3.8 版的新Function。

    • 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 *)
    • C14N 2.0Writer。参数与canonicalize()函数的参数相同。此类不构建树,而是使用* write *函数将回调事件直接转换为序列化形式。

3.8 版的新Function。

XMLParser Objects

    • class * xml.etree.ElementTree. XMLParser(** target = None encoding = None *)
    • 此类是模块的低级构建块。它使用xml.parsers.expat进行有效的基于事件的 XML 解析。可以使用feed()方法以增量方式馈送 XML 数据,并将解析事件转换为推入 API-pass调用* target 对象上的回调。如果Ellipsis target ,则使用标准TreeBuilder。如果给出 encoding * [1],则该值将覆盖 XML 文件中指定的编码。

在版本 3.8 中更改:参数现在为keyword-only。 * html *参数不再受支持。

  • close ( )

    • 完成将数据提供给解析器。返回调用在构造过程中传递的* target *的close()方法的结果;默认情况下,这是顶级文档元素。
  • feed(* data *)

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

XMLParser.feed()为每个开始标记调用* target start(tag, attrs_dict)方法,为每个结束标记调用end(tag)方法,并且数据由data(data)处理。有关进一步支持的回调方法,请参见TreeBuilder类。 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

XMLPullParser Objects

    • class * xml.etree.ElementTree. XMLPullParser(* events = None *)
    • 适用于非阻塞应用程序的拉式解析器。它的 Importing 端 API 与XMLParser相似,但是XMLPullParser不会将调用推送到回调目标,而是收集内部解析事件列表,并允许用户从中读取内容。 * events 是要报告的一系列事件。支持的事件是字符串"start""end""comment""pi""start-ns""end-ns"(“ ns”事件用于获取详细的名称空间信息)。如果Ellipsis events *,则仅报告"end"个事件。
  • feed(* data *)

    • 将给定的字节数据 Importing 解析器。
  • close ( )

    • 向解析器发送 signal,告知数据流已终止。与XMLParser.close()不同,此方法始终返回None。解析器关闭时尚未检索到的任何事件仍可以使用read_events()读取。
  • read_events ( )

    • 返回迭代器,该迭代器将在馈送到解析器的数据中遇到的事件进行处理。迭代器产生(event, elem)对,其中* event 是表示事件类型的字符串(例如"end"), elem *是遇到的Element对象或其他上下文值,如下所示。
  • startend:当前元素。

  • commentpi:当前 Comments/处理指令

  • start-ns:Tuples(prefix, uri)命名语句的名称空间 Map。

  • end-nsNone(在将来的版本中可能会更改)

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

Note

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

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

3.4 版的新Function。

在 3.8 版中进行了更改:添加了commentpi事件。

Exceptions

  • 类别 xml.etree.ElementTree. ParseError

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

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

      • line column *数字 Tuples,指定发生错误的位置。

Footnotes