On this page
19.7. xml.etree.ElementTree — ElementTree XML API
2.5 版的新Function。
源代码: Lib/xml/etree/ElementTree.py
Element类型是一个灵活的容器对象,旨在将分层数据结构存储在内存中。类型可以描述为列表和字典之间的交叉。
Warning
xml.etree.ElementTree模块不能安全防范恶意构建的数据。如果您需要解析不可信或未经身份验证的数据,请参见XML vulnerabilities。
每个元素都有许多与之关联的属性:
一个标记,它是一个字符串,用于标识此元素表示什么类型的数据(换句话说,元素类型)。
存储在 Python 字典中的许多属性。
文本字符串。
可选的尾弦。
以 Python 序列存储的许多子元素
要创建元素实例,请使用Element构造函数或SubElement()工厂函数。
ElementTree类可用于包装元素结构,并将其与 XML 相互转换。
此 API 的 C 实现以xml.etree.cElementTree
的形式提供。
有关教程和指向其他文档的链接,请参见http://effbot.org/zone/element-index.htm。 Fredrik Lundh 的页面也是 xml.etree.ElementTree 开发版本的位置。
在 2.7 版中进行了更改:ElementTree API 已更新为 1.3. 有关更多信息,请参见介绍 ElementTree 1.3。
19.7.1. Tutorial
这是使用xml.etree.ElementTree(简称ET
)的简短教程。目的是演示该模块的一些构建模块和基本概念。
19.7.1.1. XML 树和元素
XML 是一种固有的分层数据格式,最自然的表示方法是使用树。 ET
为此具有两个类-ElementTree表示整个 XML 文档为树,而Element表示此树中的单个节点。与整个文档的交互(读写文件)通常在ElementTree级别进行。与单个 XML 元素及其子元素的交互在Element级别完成。
19.7.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 从字符串直接解析为Element,而Element是解析树的根元素。其他解析函数可能会创建ElementTree。检查文档以确保。
作为Element,root
具有标签和属性字典:
>>> 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'
19.7.1.3. 寻找有趣的元素
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可以更精确地指定要查找的元素。
19.7.1.4. 修改 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>
19.7.1.5. 构建 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>
19.7.1.6. 使用命名空间解析 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
19.7.1.7. 额外资源
有关教程和指向其他文档的链接,请参见http://effbot.org/zone/element-index.htm。
19.7.2. XPath 支持
此模块仅对XPath expressions提供了对树中元素定位的支持。目标是支持缩写语法的一小部分。完整的 XPath 引擎不在模块范围内。
19.7.2.1. 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]")
19.7.2.2. 支持的 XPath 语法
Syntax | Meaning |
---|---|
tag |
选择具有给定标签的所有子元素。例如,spam 选择所有名为spam 的子元素,spam/egg 选择所有名为spam 的子代中的所有子孙egg 。 |
* |
选择所有子元素。例如,*/egg 选择所有名为egg 的孙子。 |
. |
选择当前节点。这在路径开始时最有用,表示它是相对路径。 |
// |
选择当前元素下方所有级别上的所有子元素。例如,.//egg 选择整个树中的所有egg 元素。 |
.. |
选择父元素。 |
[@attrib] |
选择具有给定属性的所有元素。 |
[@attrib='value'] |
选择给定属性具有给定值的所有元素。该值不能包含引号。 |
[tag] |
选择所有具有名为tag 的子元素的元素。仅支持直子。 |
[tag='text'] |
选择所有具有名为tag 的子元素的元素,其完整文本内容(包括后代)等于给定的text 。 |
[position] |
选择位于给定位置的所有元素。该位置可以是整数(1 是第一个位置),表达式last() (用于最后一个位置),也可以是相对于最后一个位置的位置(例如last()-1 )。 |
谓词(方括号内的表达式)之前必须带有标签名称,星号或其他谓词。 position
谓词必须以标签名称开头。
19.7.3. Reference
19.7.3.1. Functions
xml.etree.ElementTree.
Comment
(* text = None *)- Comments 元素工厂。此工厂函数创建一个特殊元素,该元素将由标准序列化程序序列化为 XMLComments。Comments 字符串可以是字节字符串或 Unicode 字符串。 * text *是包含 Comments 字符串的字符串。返回表示 Comments 的元素实例。
xml.etree.ElementTree.
dump
(* elem *)- 将元素树或元素结构写入 sys.stdout。此Function应仅用于调试。
确切的输出格式取决于实现。在此版本中,它是作为普通 XML 文件编写的。
- elem *是元素树或单个元素。
xml.etree.ElementTree.
fromstring
(* text *)xml.etree.ElementTree.
fromstringlist
(* sequence , parser = None *)
2.7 版的新Function。
xml.etree.ElementTree.
iselement
(* element *)- 检查对象是否看起来是有效的元素对象。 * element *是一个元素实例。如果这是一个元素对象,则返回一个真值。
xml.etree.ElementTree.
iterparse
(* source , events = None , parser = None *)
Note
iterparse()仅保证在发出“开始”事件时已看到开始标记的“>”字符,因此定义了属性,但是此时未定义 text 和 tail 属性的内容。这同样适用于子元素。它们可能存在也可能不存在。
如果需要完全填充的元素,请查找“结束”事件。
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 内容(如果给定)的字符串。返回表示处理指令的元素实例。
xml.etree.ElementTree.
register_namespace
(前缀,* uri *)- 注册名称空间前缀。该注册表是全局注册表,并且将删除给定前缀或名称空间 URI 的所有现有 Map。 * prefix *是名称空间前缀。 * uri *是名称空间 uri。如果可能,将使用给定的前缀序列化该命名空间中的标签和属性。
2.7 版的新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.etree.ElementTree.
tostringlist
(* element , encoding =“ us-ascii” , method =“ xml” *)
2.7 版的新Function。
xml.etree.ElementTree.
XML
(* text , parser = None *)xml.etree.ElementTree.
XMLID
(* text , parser = None *)
19.7.3.2. 元素对象
-
- class *
xml.etree.ElementTree.
Element
(* tag , attrib ={} ,** extra *)
- 元素类。此类定义 Element 接口,并提供此接口的参考实现。
- class *
元素名称,属性名称和属性值可以是字节字符串或 Unicode 字符串。 * tag *是元素名称。 * attrib *是一个可选的字典,包含元素属性。 * extra *包含其他属性,以关键字参数形式给出。
tag
- 一个字符串,用于标识此元素表示什么类型的数据(换句话说,元素类型)。
text
tail
- 这些属性可用于保存与元素关联的其他数据。它们的值通常是字符串,但可以是任何特定于应用程序的对象。如果该元素是从 XML 文件创建的,则* text 属性将保留元素的开始标签和其第一个子标签或结束标签之间的文本,或者
None
,而 tail *属性将保留元素的结束标签之间的文本。和下一个标记,或None
。对于 XML 数据
- 这些属性可用于保存与元素关联的其他数据。它们的值通常是字符串,但可以是任何特定于应用程序的对象。如果该元素是从 XML 文件创建的,则* text 属性将保留元素的开始标签和其第一个子标签或结束标签之间的文本,或者
<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
。
- 重置元素。此函数删除所有子元素,清除所有属性,并将 text 和 tail 属性设置为
get
(* key , default = None *)- 获取名为* key *的元素属性。
返回属性值,如果未找到属性,则返回* default *。
items
( )- 以(名称,值)对的序列形式返回元素属性。属性以任意 Sequences 返回。
keys
( )- 返回元素属性名称作为列表。名称以任意 Sequences 返回。
set
(* key , value *)- 将元素上的属性* key 设置为 value *。
以下方法适用于元素的子元素(子元素)。
append
(* subelement *)- 将元素* subelement *添加到此元素内部子元素列表的末尾。
extend
(子元素)- 从具有零个或多个元素的序列对象中追加子元素。如果子元素不是有效的对象,则引发AssertionError。
2.7 版的新Function。
find
(* match *)- 查找匹配* match *的第一个子元素。 * match *可以是标签名称或路径。返回元素实例或
None
。
- 查找匹配* match *的第一个子元素。 * match *可以是标签名称或路径。返回元素实例或
findall
(* match *)- pass标签名称或路径查找所有匹配的子元素。返回包含所有按文档 Sequences 匹配的元素的列表。
findtext
(* match , default = None *)- 查找与* match *匹配的第一个子元素的文本。 * match 可以是标签名称或路径。返回第一个匹配元素的文本内容;如果未找到任何元素,则返回 default *。请注意,如果匹配的元素没有文本内容,则返回一个空字符串。
getchildren
( )- 从 2.7 版开始不推荐使用:使用
list(elem)
或迭代。
- 从 2.7 版开始不推荐使用:使用
getiterator
(* tag = None *)- 从 2.7 版开始不推荐使用:而是使用方法Element.iter()。
insert
(* index , element *)- 在此元素的给定位置插入一个子元素。
iter
(* tag = None *)- 创建一个以当前元素为根的树iterator。迭代器按照文档(深度优先)的 Sequences 遍历此元素及其下的所有元素。如果* tag 不是
None
或'*'
,则仅从迭代器返回其标签等于 tag *的元素。如果在迭代过程中修改树结构,则结果不确定。
- 创建一个以当前元素为根的树iterator。迭代器按照文档(深度优先)的 Sequences 遍历此元素及其下的所有元素。如果* tag 不是
2.7 版的新Function。
iterfind
(* match *)- pass标签名称或路径查找所有匹配的子元素。返回一个可迭代的结果,按文档 Sequences 生成所有匹配的元素。
2.7 版的新Function。
itertext
( )- 创建一个文本迭代器。迭代器按文档 Sequences 循环遍历此元素和所有子元素,并返回所有内部文本。
2.7 版的新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"
19.7.3.3. ElementTree 对象
-
- class *
xml.etree.ElementTree.
ElementTree
(* element = None , file = None *)
- ElementTree 包装器类。此类表示整个元素层次结构,并为与标准 XML 之间的序列化添加了一些额外的支持。
- class *
- element *是根元素。如果指定了树,则使用 XML * file *的内容进行初始化。
_setroot
(元素)- 替换此树的根元素。这将丢弃树的当前内容,并将其替换为给定的元素。小心使用。 * element *是一个元素实例。
find
(* match *)- 与Element.find()相同,从树的根部开始。
findall
(* match *)- 与Element.findall()相同,从树的根部开始。
findtext
(* match , default = None *)- 与Element.findtext()相同,从树的根部开始。
getiterator
(* tag = None *)- 从 2.7 版开始不推荐使用:而是使用方法ElementTree.iter()。
getroot
( )- 返回此树的根元素。
iter
(* tag = None *)- 为根元素创建并返回一个树迭代器。迭代器按节 Sequences 遍历此树中的所有元素。 * tag *是要查找的标签(默认为返回所有元素)。
iterfind
(* match *)- pass标签名称或路径查找所有匹配的子元素。与 getroot()。iterfind(match)相同。返回一个可迭代的结果,按文档 Sequences 生成所有匹配的元素。
2.7 版的新Function。
parse
(* source , parser = None *)- 将外部 XML 节加载到此元素树中。 * source *是文件名或文件对象。 * parser *是可选的解析器实例。如果未给出,则使用标准 XMLParser 解析器。返回节根元素。
write
(* file , encoding =“ us-ascii” , xml_declaration = None , default_namespace = None , method =“ xml” *)- 将元素树作为 XML 写入文件。 * file *是文件名,或为写入而打开的文件对象。 * encoding * [1]是输出编码(默认为 US-ASCII)。 * xml_declaration *控制是否应将 XML 语句添加到文件中。如果不使用 US-ASCII 或 UTF-8(默认值为
None
),则永远不要使用False
,永远使用True
,永远使用None
。 * default_namespace *设置默认的 XML 名称空间(用于“ xmlns”)。 方法是"xml"
,"html"
或"text"
(默认为"xml"
)。返回编码的字符串。
- 将元素树作为 XML 写入文件。 * file *是文件名,或为写入而打开的文件对象。 * encoding * [1]是输出编码(默认为 US-ASCII)。 * xml_declaration *控制是否应将 XML 语句添加到文件中。如果不使用 US-ASCII 或 UTF-8(默认值为
这是将要处理的 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")
19.7.3.4. QName 对象
-
- class *
xml.etree.ElementTree.
QName
(* text_or_uri , tag = None *)
- QName 包装器。这可以用来包装 QName 属性值,以便对输出进行正确的名称空间处理。 * text_or_uri 是一个包含 QName 值的字符串,格式为\ {} local,或者,如果给出了 tag 参数,则为 QName 的 URI 部分。如果给出 tag *,则第一个参数解释为 URI,而该参数解释为本地名称。 QName个实例不透明。
- class *
19.7.3.5. TreeBuilder 对象
类别
xml.etree.ElementTree.
TreeBuilder
(* element_factory = None *)- 通用元素结构生成器。该构建器将开始,数据和结束方法调用的序列转换为格式良好的元素结构。您可以使用此类使用自定义 XML 解析器或某些其他类似 XML 格式的解析器来构建元素结构。如果给定,将调用* element_factory *以创建新的Element实例。
close
( )- 刷新构建器缓冲区,并返回顶级文档元素。返回一个Element实例。
data
(* data *)- 将文本添加到当前元素。 * data *是一个字符串。这应该是字节字符串或 Unicode 字符串。
end
(标签)- 关闭当前元素。 * tag *是元素名称。返回封闭的元素。
start
(* tag , attrs *)- 打开一个新元素。 * tag *是元素名称。 * attrs *是包含元素属性的字典。返回打开的元素。
此外,自定义TreeBuilder对象可以提供以下方法:
doctype
(* name , pubid , system *)- 处理文档类型语句。 * name *是文档类型名称。 * pubid *是公共标识符。 * system *是系统标识符。默认的TreeBuilder类不存在此方法。
2.7 版的新Function。
19.7.3.6. XMLParser 对象
-
- class *
xml.etree.ElementTree.
XMLParser
(* html = 0 , target = None , encoding = None *)
- class *
close
( )- 完成将数据提供给解析器。返回元素结构。
doctype
(* name , pubid , system *)- 从 2.7 版开始不推荐使用:在自定义 TreeBuilder 目标上定义TreeBuilder.doctype()方法。
feed
(* data *)- 将数据提供给解析器。 * data *是编码数据。
XMLParser.feed()为每个开始标记调用* target 的start()
方法,为每个结束标记调用end()
方法,并且数据由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
Footnotes
- 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。