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 vulnerabilities

20.5.1. Tutorial

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

20.5.1.1. XML tree and elements

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

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

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

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构造函数来访问文档类型声明。

20.5.1.3. Pull API for non-blocking parsing

该模块提供的大多数解析函数要求在返回任何结果之前立即读取整个文档。可以使用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文档,而不想把它全部保存在内存中时,它是有用的。

20.5.1.4. Finding interesting elements

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可以更精确地指定要查找的元素。

20.5.1.5. Modifying an XML File

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

Once created, an Element object may be manipulated by directly changing its fields (such as Element.text), adding and modifying attributes (Element.set() method), as well as adding new children (for example with Element.append()).

假设我们要向每个国家/地区的排名添加一个,并向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. Building XML documents

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. Parsing XML with Namespaces

If the XML input has namespaces, tags and attributes with prefixes in the form prefix:sometag get expanded to {uri}sometag where the prefix is replaced by the full 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. Additional resources

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

20.5.2. XPath support

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

20.5.2.1. Example

这里有一个例子演示了模块的一些XPath功能。我们将使用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]")

20.5.2.2. Supported XPath syntax

句法含义
tag选择具有给定标签的所有子元素。例如,spam选择所有名为spam的子元素,spam/egg选择所有名为egg的孙子名为spam的儿童。
*选择所有子元素。例如,*/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. Reference

20.5.3.1. Functions

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文档。序列是包含XML数据片段的列表或其他序列。parser是一个可选的解析器实例。如果未给出,则使用标准的XMLParser解析器。返回Element实例。

版本3.2中的新功能。

xml.etree.ElementTree.iselement(element)

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

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

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

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

注意

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

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

自版本3.4后弃用: 解析器参数。

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

将XML节解析到元素树中。是包含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的任何现有映射。前缀是命名空间前缀。uri是一个命名空间uri。此命名空间中的标签和属性将使用给定的前缀进行序列化,如果可能的话。

版本3.2中的新功能。

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

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

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

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

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

版本3.4中的新功能: short_empty_elements参数。

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

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

版本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. Element Objects

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

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

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

tag

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

text
tail

这些属性可用于保存与元素关联的其他数据。它们的值通常是字符串,但可以是任何特定于应用程序的对象。If the element is created from an XML file, the text attribute holds either the text between the element’s start tag and its first child or end tag, or None, and the tail attribute holds either the text between the element’s end tag and the next tag, or None. 对于XML数据

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

the a element has None for both text and tail attributes, the b element has text "1" and tail "4", the c element has text "2" and tail None, and the d element has text None and tail "3".

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

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

attrib

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

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

clear()

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

get(key, default=None)

获取名为的元素属性。

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

items()

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

keys()

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

set(key, value)

将元素上的属性设置为

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

append(subelement)

将元素子元素添加到此元素的内部子元素列表的末尾。引发TypeError如果子元素不是Element

extend(subelements)

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

版本3.2中的新功能。

find(match, namespaces=None)

查找与匹配匹配的第一个子元素。match可以是标记名称或path返回元素实例或None命名空间是从命名空间前缀到全名的可选映射。

findall(match, namespaces=None)

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

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

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

getchildren()

自版本3.2后已弃用:使用list(elem)或迭代。

getiterator(tag=None)

自版本3.2后已弃用:改用了方法Element.iter()

insert(index, subelement)

在此元素中的给定位置插入子元素引发TypeError如果子元素不是Element

iter(tag=None)

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

版本3.2中的新功能。

iterfind(match, namespaces=None)

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

版本3.2中的新功能。

itertext()

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

版本3.2中的新功能。

makeelement(tag, attrib)

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

remove(subelement)

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

Element objects also support the following sequence type methods for working with subelements: __delitem__(), __getitem__(), __setitem__(), __len__().

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

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 Objects

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

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

元素是根元素。如果给定,则使用XML 文件的内容初始化树。

_setroot(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)

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

iterfind(match, namespaces=None)

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

版本3.2中的新功能。

parse(source, parser=None)

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

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

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

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

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

更改第一段中每个链接的属性“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")

20.5.3.4. QName Objects

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

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

20.5.3.5. TreeBuilder Objects

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

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

close()

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

data(data)

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

end(tag)

关闭当前元素。标签是元素名称。返回关闭的元素。

start(tag, attrs)

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

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

doctype(name, pubid, system)

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

版本3.2中的新功能。

20.5.3.6. XMLParser Objects

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

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

自版本3.4后弃用: html参数。其余的参数应通过关键字传递,以准备删除html参数。

close()

完成向解析器提供数据。返回调用构建期间传递的目标close()方法的结果;默认情况下,这是toplevel文档元素。

doctype(name, pubid, system)

自版本3.2后弃用:在自定义TreeBuilder目标上定义TreeBuilder.doctype()方法。

feed(data)

将数据馈送到解析器。data是编码数据。

XMLParser.feed()调用目标开始(标签, attrs_dict)方法,其每个结束标签的end(tag)方法,并且通过方法data(data)处理数据。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

20.5.3.7. XMLPullParser Objects

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

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

feed(data)

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

close()

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

read_events()

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

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

注意

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

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

版本3.4中的新功能。

20.5.3.8. Exceptions

class xml.etree.ElementTree.ParseError

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

code

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

position

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

脚注

[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