xml.etree.ElementTree --- ElementTree XML API?
源代碼: Lib/xml/etree/ElementTree.py
xml.etree.ElementTree 模塊實現(xiàn)了一個簡單高效的API,用于解析和創(chuàng)建XML數(shù)據(jù)。
在 3.3 版更改: 此模塊將在可能的情況下使用快速實現(xiàn)。
3.3 版后已移除: xml.etree.cElementTree 模塊已被棄用。
警告
xml.etree.ElementTree 模塊對于惡意構(gòu)建的數(shù)據(jù)是不安全的。如果需要解析不可信或未經(jīng)身份驗證的數(shù)據(jù),請參見 XML 漏洞 。
教程?
這是一個使用 xml.etree.ElementTree (簡稱 ET )的簡短教程。目標是演示模塊的一些構(gòu)建塊和基本概念。
XML 樹和元素?
XML 是一種繼承性的分層數(shù)據(jù)格式,最自然的表示方法是使用樹。 為此, ET 有兩個類 -- ElementTree 將整個XML文檔表示為一個樹, Element 表示該樹中的單個節(jié)點。 與整個文檔的交互(讀寫文件)通常在 ElementTree 級別完成。 與單個 XML 元素及其子元素的交互是在 Element 級別完成的。
解析 XML?
我們將使用以下 XML 文檔作為本節(jié)的示例數(shù)據(jù):
<?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>
可以通過從文件中讀取來導入此數(shù)據(jù):
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 ,該元素是已解析樹的根元素。 其他解析函數(shù)可能會創(chuàng)建一個 ElementTree 。 確切信息請查閱文檔。
作為 Element , root 具有標簽和屬性字典:
>>> root.tag
'data'
>>> root.attrib
{}
還有可以迭代的子節(jié)點:
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
子級是可以嵌套的,我們可以通過索引訪問特定的子級節(jié)點:
>>> root[0][1].text
'2008'
備注
并非 XML 輸入的所有元素都將作為解析樹的元素結(jié)束。 目前,此模塊跳過輸入中的任何 XML 注釋、處理指令和文檔類型聲明。 然而,使用這個模塊的 API 而不是從 XML 文本解析構(gòu)建的樹可以包含注釋和處理指令,生成 XML 輸出時同樣包含這些注釋和處理指令。 可以通過將自定義 TreeBuilder 實例傳遞給 XMLParser 構(gòu)造器來訪問文檔類型聲明。
用于非阻塞解析的拉取 API?
此模塊所提供了大多數(shù)解析函數(shù)都要求在返回任何結(jié)果之前一次性讀取整個文檔。 可以使用 XMLParser 并以增量方式添加數(shù)據(jù),但這是在回調(diào)目標上調(diào)用方法的推送式 API。 有時用戶真正想要的是能夠以增量方式解析 XML 而無需阻塞操作,同時享受完整的已構(gòu)造 Element 對象。
針對此需求的最強大工具是 XMLPullParser。 它不要求通過阻塞式讀取來獲得 XML 數(shù)據(jù),而是通過執(zhí)行 XMLPullParser.feed() 調(diào)用來增量式地添加數(shù)據(jù)。 要獲得已解析的 XML 元素,應調(diào)用 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 數(shù)據(jù)時造成阻塞但仍希望具有增量解析能力,可以考慮 iterparse()。 它在你讀取大型 XML 文檔并且不希望將它完全放去內(nèi)存時會很適用。
查找感興趣的元素?
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() 找?guī)в刑囟撕灥?第一個 子級,然后可以用 Element.text 訪問元素的文本內(nèi)容。 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 提供了一種構(gòu)建XML文檔并將其寫入文件的簡單方法。調(diào)用 ElementTree.write() 方法就可以實現(xiàn)。
創(chuàng)建后可以直接操作 Element 對象。例如:使用 Element.text 修改文本字段,使用 Element.set() 方法添加和修改屬性,以及使用 Element.append() 添加新的子元素。
假設我們要為每個國家/地區(qū)的中添加一個排名,并在排名元素中添加一個 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現(xiàn)在看起來像這樣:
<?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的所有國家/地區(qū):
>>> 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')
請注意在迭代時進行并發(fā)修改可能會導致問題,就像在迭代并修改 Python 列表或字典時那樣。 因此,這個示例先通過 root.findall() 收集了所有匹配的元素,在此之后再對匹配項列表進行迭代。
生成的XML現(xiàn)在看起來像這樣:
<?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>
構(gòu)建 XML 文檔?
SubElement() 函數(shù)還提供了一種便捷方法來為給定元素創(chuàng)建新的子元素:
>>> 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 輸入帶有 命名空間,則具有前綴的 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 示例的一種方式是手動為 find() 或 findall() 的 xpath 中的每個標記或?qū)傩蕴砑?URI:
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 示例創(chuàng)建一個字典來存放你自己的前綴并在搜索函數(shù)中使用它們:
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
XPath支持?
此模塊提供了對 XPath 表達式 的有限支持用于在樹中定位元素。 其目標是支持一個簡化語法的較小子集;完整的 XPath 引擎超出了此模塊的適用范圍。
示例?
下面是一個演示此模塊的部分 XPath 功能的例子。 我們將使用來自 解析 XML 小節(jié)的 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語法?
語法 |
含意 |
|---|---|
|
選擇具有給定標記的所有子元素。 例如, 在 3.8 版更改: 增加了對星號通配符的支持。 |
|
選擇所有子元素,包括注釋和處理說明。例如 |
|
選擇當前節(jié)點。這在路徑的開頭非常有用,用于指示它是相對路徑。 |
|
選擇所有子元素 在當前元素的所有下級中選擇所有下級元素。 例如, |
|
選擇父元素。 如果路徑試圖前往起始元素的上級(元素的 |
|
選擇具有給定屬性的所有元素。 |
|
選擇給定屬性具有給定值的所有元素。該值不能包含引號。 |
|
選擇給定屬性不具有給定值的所有元素。 該值不能包含引號。 3.10 新版功能. |
|
選擇所有包含 |
|
選擇完整文本內(nèi)容等于 3.7 新版功能. |
|
選擇完整文本內(nèi)容包括其下級內(nèi)容不等于給定的 3.10 新版功能. |
|
選擇所有包含名為 |
|
選擇具有名為 3.10 新版功能. |
|
選擇位于給定位置的所有元素。 位置可以是一個整數(shù) (1 表示首位),表達式 |
謂詞(方括號內(nèi)的表達式)之前必須帶有標簽名稱,星號或其他謂詞。position 謂詞前必須有標簽名稱。
參考?
函數(shù)?
- xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)?
C14N 2.0 轉(zhuǎn)換功能。.
規(guī)整化是標準化 XML 輸出的一種方式,該方式允許按字節(jié)比較和數(shù)字簽名。 它降低了 XML 序列化器所具有的自由度并改為生成更受約束的 XML 表示形式。 主要限制涉及命名空間聲明的位置、屬性的順序和可忽略的空白符等。
此函數(shù)接受一個 XML 數(shù)字字符串 (xml_data) 或文件路徑或者文件類對象 (from_file) 作為輸入,將其轉(zhuǎn)換為規(guī)整形式,并在提供了 out 文件(類)對象的情況下將其寫到該對象的話,或者如果未提供則將其作為文本字符串返回。 輸出文件接受文本而非字節(jié)數(shù)據(jù)。 因此它應當以使用
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)
配置選項 options 如下:
with_comments: 設為真值以包括注釋 (默認為假值)
- strip_text: 設為真值以去除文本內(nèi)容前后的空白符
(默認值:否)
- rewrite_prefixes: 設為真值以替換帶有 "n{number}" 前綴的命名空間
(默認值:否)
- qname_aware_tags: 一組可感知限定名稱的標記名稱,其中的前綴
應當在文本內(nèi)容中被替換 (默認為空值)
- qname_aware_attrs: 一組可感知限定名稱的屬性名稱,其中的前綴
應當在文本內(nèi)容中被替換 (默認為空值)
exclude_attrs: 一組不應當被序列化的屬性名稱
exclude_tags: 一組不應當被序列化的標記名稱
在上面的選項列表中,"一組" 是指任意多項集或包含字符串的可迭代對象,排序是不必要的。
3.8 新版功能.
- xml.etree.ElementTree.Comment(text=None)?
注釋元素工廠函數(shù)。 這個工廠函數(shù)可創(chuàng)建一個特殊元素,它將被標準序列化器當作 XML 注釋來進行序列化。 注釋字串可以是字節(jié)串或是 Unicode 字符串。 text 是包含注釋字串的字符串。 返回一個表示注釋的元素實例。
請注意
XMLParser會跳過輸入中的注釋而不會為其創(chuàng)建注釋對象。ElementTree將只在當使用某個Element方法向樹插入了注釋節(jié)點時才會包含注釋節(jié)點。
- xml.etree.ElementTree.dump(elem)?
將一個元素樹或元素結(jié)構(gòu)體寫入到 sys.stdout。 此函數(shù)應當只被用于調(diào)試。
實際輸出格式是依賴于具體實現(xiàn)的。 在這個版本中,它將以普通 XML 文件的格式寫入。
elem 是一個元素樹或單獨元素。
在 3.8 版更改:
dump()函數(shù)現(xiàn)在會保留用戶指定的屬性順序。
- xml.etree.ElementTree.fromstring(text, parser=None)?
根據(jù)一個字符串常量解析 XML 的節(jié)。 與
XML()類似。 text 是包含 XML 數(shù)據(jù)的字符串。 parser 是可選的解析器實例。 如果未給出,則會使用標準XMLParser解析器。 返回一個Element實例。
- xml.etree.ElementTree.fromstringlist(sequence, parser=None)?
根據(jù)一個字符串片段序列解析 XML 文檔。 sequence 是包含 XML 數(shù)據(jù)片段的列表或其他序列對象。 parser 是可選的解析器實例。 如果未給出,則會使用標準的
XMLParser解析器。 返回一個Element實例。3.2 新版功能.
- xml.etree.ElementTree.indent(tree, space=' ', level=0)?
添加空格到子樹來實現(xiàn)樹的縮進效果。 這可以被用來生成美化打印的 XML 輸出。 tree 可以為 Element 或 ElementTree。 space 是對應將被插入的每個縮進層級的空格字符串,默認為兩個空格符。 要對已縮進的樹的部分子樹進行縮進,請傳入初始縮進層級作為 level。
3.9 新版功能.
- xml.etree.ElementTree.iselement(element)?
檢測一個對象是否為有效的元素對象。 element 是一個元素實例。 如果對象是一個元素對象則返回
True。
- xml.etree.ElementTree.iterparse(source, events=None, parser=None)?
以增量方式將一個 XML 節(jié)解析為元素樹,并向用戶報告執(zhí)行情況。 source 是包含 XML 數(shù)據(jù)的文件名或 file object。 events 是要報告的事件序列。 所支持的事件字符串有
"start","end","comment","pi","start-ns"和"end-ns"("ns" 事件用于獲取詳細的命名空間信息)。 如果 events 被省略,則只有"end"事件會被報告。 parser 是可選的解析器實例。 如果未給出,則會使用標準的XMLParser解析器。 parser 必須為XMLParser的子類并且只能使用默認的TreeBuilder作為目標。 返回一個提供(event, elem)對的 iterator。請注意雖然
iterparse()是以增量方式構(gòu)建樹,但它會對 source (或其所指定的文件) 發(fā)出阻塞式讀取。 因此,它不適用于不可執(zhí)行阻塞式讀取的應用。 對于完全非阻塞式的解析,請參看XMLPullParser。備注
iterparse()只會確保當發(fā)出 "start" 事件時看到了開始標記的 ">" 字符,因而在這個點上屬性已被定義,但文本容和末尾屬性還未被定義。 這同樣適用于元素的下級;它們可能存在也可能不存在。如果你需要已完全填充的元素,請改為查找 "end" 事件。
3.4 版后已移除: parser 參數(shù)。
在 3.8 版更改: 增加了
comment和pi事件。
- xml.etree.ElementTree.parse(source, parser=None)?
將一個 XML 的節(jié)解析為元素樹。 source 是包含 XML 數(shù)據(jù)的文件名或文件對象。 parser 是可選的解析器實例。 如果未給出,則會使用標準的
XMLParser解析器。 返回一個ElementTree實例。
- xml.etree.ElementTree.ProcessingInstruction(target, text=None)?
PI 元素工廠函數(shù)。 這個工廠函數(shù)可創(chuàng)建一個特殊元素,它將被當作 XML 處理指令來進行序列化。 target 是包含 PI 目標的字符串。 text 如果給出則是包含 PI 內(nèi)容的字符串。 返回一個表示處理指令的元素實例。
請注意
XMLParser會跳過輸入中的處理指令而不會為其創(chuàng)建注釋對象。ElementTree將只在當使用某個Element方法向樹插入了處理指令節(jié)點時才會包含處理指令節(jié)點。
- xml.etree.ElementTree.register_namespace(prefix, uri)?
注冊一個命名空間前綴。 這個注冊表是全局的,并且任何對應給定前綴或命名空間 URI 的現(xiàn)有映射都會被移除。 prefix 是命名空間前綴。 uri 是命名空間 URI。 如果可能的話,這個命名空間中的標記和屬性將附帶給定的前綴來進行序列化。
3.2 新版功能.
- xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)?
子元素工廠函數(shù)。 這個函數(shù)會創(chuàng)建一個元素實例,并將其添加到現(xiàn)有的元素。
元素名、屬性名和屬性值可以是字節(jié)串或 Unicode 字符串。 parent 是父元素。 tag 是子元素名。 attrib 是一個可選的字典,其中包含元素屬性。 extra 包含額外的屬性,以關(guān)鍵字參數(shù)形式給出。 返回一個元素實例。
- 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 字符串(否則生成字節(jié)串)。 method 是"xml","html"或"text"(默認為"xml")。 xml_declaration, default_namespace 和 short_empty_elements 具有與ElementTree.write()中一致的含義。 返回一個包含 XML 數(shù)據(jù)(可選)已編碼的字符串。3.4 新版功能: short_empty_elements 形參。
3.8 新版功能: xml_declaration 和 default_namespace 形參。
在 3.8 版更改:
tostring()函數(shù)現(xiàn)在會保留用戶指定的屬性順序。
- 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 字符串(否則生成字節(jié)串)。 method 是"xml","html"或"text"(默認為"xml")。 xml_declaration, default_namespace 和 short_empty_elements 具有與ElementTree.write()中一致的含義。 返回一個包含 XML 數(shù)據(jù)(可選)已編碼字符串的列表。 它并不保證任何特定的序列,除了b"".join(tostringlist(element)) == tostring(element)。3.2 新版功能.
3.4 新版功能: short_empty_elements 形參。
3.8 新版功能: xml_declaration 和 default_namespace 形參。
在 3.8 版更改:
tostringlist()函數(shù)現(xiàn)在會保留用戶指定的屬性順序。
XInclude 支持?
此模塊通過 xml.etree.ElementInclude 輔助模塊提供了對 XInclude 指令 的有限支持,這個模塊可被用來根據(jù)元素樹的信息在其中插入子樹和文本字符串。
示例?
以下是一個演示 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 元素。 結(jié)果看起來大概是這樣:
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<para>This is a paragraph.</para>
</document>
如果省略了 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>
結(jié)果可能如下所示:
<document xmlns:xi="http://www.w3.org/2001/XInclude">
Copyright (c) 2003.
</document>
參考?
函數(shù)?
- xml.etree.ElementInclude.default_loader(href, parse, encoding=None)?
默認的加載器。 這個默認的加載器會從磁盤讀取所包括的資源。 href 是一個 URL。 parse 是 "xml" 或 "text" 表示解析模式。 encoding 是可選的文本編碼格式。 如果未給出,則編碼格式為
utf-8。 返回已擴展的資源。 如果解析模式為"xml",則它是一個 ElementTree 實例。 如果解析模式為 "text",則它是一個 Unicode 字符串。 如果加載器失敗,它可以返回 None 或者引發(fā)異常。
- xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)?
這個函數(shù)會擴展 XInclude 指令。 elem 是根元素。 loader 是可選的資源加載器。 如果省略,則它默認為
default_loader()。 如果給出,則它應當是一個實現(xiàn)了與default_loader()相同的接口的可調(diào)用對象。 base_url 是原文件的基準 URL,用于求解相對的包括文件引用。 max_depth 是遞歸包括的最大數(shù)量。 此限制是為了降低惡意內(nèi)容爆破的風險。 傳入一個負值可禁用此限制。返回已擴展的資源。 如果解析模式為
"xml",則它是一個 ElementTree 實例。 如果解析模式為 "text",則它是一個 Unicode 字符串。 如果加載器失敗,它可以返回 None 或者引發(fā)異常。3.9 新版功能: base_url 和 max_depth 形參。
元素對象?
- class xml.etree.ElementTree.Element(tag, attrib={}, **extra)?
元素類。 這個類定義了 Element 接口,并提供了這個接口的引用實現(xiàn)。
元素名、屬性名和屬性值可以是字節(jié)串或 Unicode 字符串。 tag 是元素名。 attrib 是一個可選的字典,其中包含元素屬性。 extra 包含額外的屬性,以關(guān)鍵字參數(shù)形式給出。
- tag?
一個標識此元素意味著何種數(shù)據(jù)的字符串(換句話說,元素類型)。
- text?
- tail?
這些屬性可被用于存放與元素相關(guān)聯(lián)的額外數(shù)據(jù)。 它們的值通常為字符串但也可以是任何應用專屬的對象。 如果元素是基于 XML 文件創(chuàng)建的,text 屬性會存放元素的開始標記及其第一個子元素或結(jié)束標記之間的文本,或者為
None,而 tail 屬性會存放元素的結(jié)束標記及下一個標記之間的文本,或者為None。 對于 XML 數(shù)據(jù)<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"。要獲取一個元素的內(nèi)部文本,請參閱
itertext(),例如"".join(element.itertext())。應用程序可以將任意對象存入這些屬性。
- attrib?
一個包含元素屬性的字典。 請注意雖然 attrib 值總是一個真正可變的 Python 字典,但 ElementTree 實現(xiàn)可以選擇其他內(nèi)部表示形式,并只在有需要時才創(chuàng)建字典。 為了發(fā)揮這種實現(xiàn)的優(yōu)勢,請在任何可能情況下使用下列字典方法。
以下字典類方法作用于元素屬性。
- clear()?
重設一個元素。 此方法會移除所有子元素,清空所有屬性,并將 text 和 tail 屬性設為
None。
- get(key, default=None)?
獲取名為 key 的元素屬性。
返回屬性的值,或者如果屬性未找到則返回 default。
- items()?
將元素屬性以 (name, value) 對序列的形式返回。 所返回屬性的順序任意。
- keys()?
將元素屬性名稱以列表的形式返回。 所返回名稱的順序任意。
- set(key, value)?
將元素的 key 屬性設為 value。
以下方法作用于元素的下級(子元素)。
- append(subelement)?
將元素 subelement 添加到此元素的子元素內(nèi)部列表。 如果 subelement 不是一個
Element則會引發(fā)TypeError。
- extend(subelements)?
使用具有零個或多個元素的序列對象添加 subelements。 如果某個子元素不是
Element則會引發(fā)TypeError。3.2 新版功能.
- find(match, namespaces=None)?
查找第一個匹配 match 的子元素。 match 可以是一個標記名稱或者 路徑。 返回一個元素實例或
None。 namespaces 是可選的從命名空間前綴到完整名稱的映射。 傳入''作為前綴可將表達式中所有無前綴的標記名稱移動到給定的命名空間。
- findall(match, namespaces=None)?
根據(jù)標記名稱或者 路徑 查找所有匹配的子元素。 返回一個包含所有匹配元素按文檔順序排序的列表。 namespaces 是可選的從命名空間前綴到完整名稱的映射。 傳入
''作為前綴可將表達式中所有無前綴的標記名稱移動到給定的命名空間。
- findtext(match, default=None, namespaces=None)?
查找第一個匹配 match 的子元素的文本。 match 可以是一個標記名稱或者 路徑。 反回第一個匹配的元素的文本內(nèi)容,或者如果元素未找到則返回 default。 請注意如果匹配的元素沒有文本內(nèi)容則會返回一個空字符串。 namespaces 是可選的從命名空間前綴到完整名稱的映射。 傳入
''作為前綴可將表達式中所有無前綴的標記名稱移動到給定的命名空間。
- insert(index, subelement)?
將 subelement 插入到此元素的給定位置中。 如果 subelement 不是一個
Element則會引發(fā)TypeError。
- iter(tag=None)?
創(chuàng)建一個以當前元素為根元素的樹的 iterator。 該迭代器將以文檔(深度優(yōu)先)順序迭代此元素及其所有下級元素。 如果 tag 不為
None或'*',則迭代器只返回標記為 tag 的元素。 如果樹結(jié)構(gòu)在迭代期間被修改,則結(jié)果是未定義的。3.2 新版功能.
- iterfind(match, namespaces=None)?
根據(jù)標記名稱或者 路徑 查找所有匹配的子元素。 返回一個按文檔順序產(chǎn)生所有匹配元素的可迭代對象。 namespaces 是可選的從命名空間前綴到完整名稱的映射。
3.2 新版功能.
- itertext()?
創(chuàng)建一個文本迭代器。 該迭代器將按文檔順序遍歷此元素及其所有子元素,并返回所有內(nèi)部文本。
3.2 新版功能.
- makeelement(tag, attrib)?
創(chuàng)建一個與此元素類型相同的新元素對象。 請不要調(diào)用此方法,而應改用
SubElement()工廠函數(shù)。
- remove(subelement)?
從元素中移除 subelement。 與 find* 方法不同的是此方法會基于實例的標識來比較元素,而不是基于標記的值或內(nèi)容。
Element對象還支持下列序列類型方法以配合子元素使用:__delitem__(),__getitem__(),__setitem__(),__len__()。注意:不帶子元素的元素將被檢測為
False。 此行為將在未來的版本中發(fā)生變化。 請改用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 之前,元素的 XML 屬性的序列化順序會通過按其名稱排序來強制使其可被預期。 由于現(xiàn)在字典已保證是有序的,這個強制重排序在 Python 3.8 中已被移除以保留原本由用戶代碼解析或創(chuàng)建的屬性順序。
通常,用戶代碼應當盡量不依賴于特定的屬性順序,因為 XML 信息設定 明確地排除了用屬性順序轉(zhuǎn)遞信息的做法。 代碼應當準備好處理任何輸入順序。 對于要求確定性的 XML 輸出的情況,例如加密簽名或檢測數(shù)據(jù)集等,可以通過規(guī)范化
canonicalize()函數(shù)來進行傳統(tǒng)的序列化。對于規(guī)范化輸出不可用但仍然要求輸出特定屬性順序的情況,代碼應當設法直接按要求的順序來創(chuàng)建屬性,以避免代碼閱讀者產(chǎn)生不匹配的感覺。 如果這一點是難以做到的,可以在序列化之前應用以下寫法來強制實現(xiàn)順序不依賴于元素的創(chuàng)建:
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 對象?
- class xml.etree.ElementTree.ElementTree(element=None, file=None)?
ElementTree 包裝器類。 這個類表示一個完整的元素層級結(jié)構(gòu),并添加了一些對于標準 XML 序列化的額外支持。
element 是根元素。 如果給出 XML file 則將使用其內(nèi)容來初始化樹結(jié)構(gòu)。
- _setroot(element)?
替換該樹結(jié)構(gòu)的根元素。 這將丟棄該樹結(jié)構(gòu)的當前內(nèi)容,并將其替換為給定的元素。 請小心使用。 element 是一個元素實例。
- find(match, namespaces=None)?
與
Element.find()類似,從樹的根節(jié)點開始。
- findall(match, namespaces=None)?
與
Element.findall()類似,從樹的根節(jié)點開始。
- findtext(match, default=None, namespaces=None)?
與
Element.findtext()類似,從樹的根節(jié)點開始。
- getroot()?
返回這個樹的根元素。
- iter(tag=None)?
創(chuàng)建并返回根元素的樹結(jié)構(gòu)迭代器。 該迭代器會以節(jié)順序遍歷這個樹的所有元素。 tag 是要查找的標記(默認返回所有元素)。
- iterfind(match, namespaces=None)?
與
Element.iterfind()類似,從樹的根節(jié)點開始。3.2 新版功能.
- parse(source, parser=None)?
將一個外部 XML 節(jié)載入到此元素樹。 source 是一個文件名或 file object。 parser 是可選的解析器實例。 如果未給出,則會使用標準的
XMLParser解析器。 返回該節(jié)的根元素。
- 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 時添加 (默認為None)。 default_namespace 設置默認 XML 命名空間 (用于 "xmlns")。 method 為"xml","html"或"text"(默認為"xml")。 僅限關(guān)鍵字形參 short_empty_elements 控制不包含內(nèi)容的元素的格式。 如為True(默認值),它們會被輸出為單個自結(jié)束標記,否則它們會被輸出為一對開始/結(jié)束標記。輸出是一個字符串 (
str) 或字節(jié)串 (bytes)。 由*encoding* 參數(shù)來控制。 如果 encoding 為"unicode",則輸出是一個字符串;否則為字節(jié)串;請注意這可能與 file 的類型相沖突,如果它是一個打開的 file object 的話;請確保你不會試圖寫入字符串到二進制流或者反向操作。3.4 新版功能: short_empty_elements 形參。
在 3.8 版更改:
write()方法現(xiàn)在會保留用戶指定的屬性順序。
這是將要被操作的 XML 文件:
<html>
<head>
<title>Example page</title>
</head>
<body>
<>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")
QName 對象?
TreeBuilder 對象?
- class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)?
通用元素結(jié)構(gòu)構(gòu)建器。 此構(gòu)建器會將包含 start, data, end, comment 和 pi 方法調(diào)用的序列轉(zhuǎn)換為格式良好的元素結(jié)構(gòu)。 你可以通過這個類使用一個自定義 XML 解析器或其他 XML 類格式的解析器來構(gòu)建元素結(jié)構(gòu)。
如果給出 element_factory,它必須為接受兩個位置參數(shù)的可調(diào)用對象:一個標記和一個屬性字典。 它預期會返回一個新的元素實例。
如果給出 comment_factory 和 pi_factory 函數(shù),它們的行為應當像
Comment()和ProcessingInstruction()函數(shù)一樣創(chuàng)建注釋和處理指令。 如果未給出,則將使用默認工廠函數(shù)。 當 insert_comments 和/或 insert_pis 為真值時,如果 comments/pis 在根元素之中(但不在其之外)出現(xiàn)則它們將被插入到樹中。- data(data)?
將文本添加到當前元素。 data 為要添加的文本。 這應當是一個字節(jié)串或 Unicode 字符串。
- end(tag)?
關(guān)閉當前元素。 tag 是元素名稱。 返回已關(guān)閉的元素。
- start(tag, attrs)?
打開一個新元素。 tag 是元素名稱。 attrs 是包含元素屬性的字典。 返回打開的元素。
- comment(text)?
使用給定的 text 創(chuàng)建一條注釋。 如果
insert_comments為真值,這還會將其添加到樹結(jié)構(gòu)中。3.8 新版功能.
- pi(target, text)?
使用給定的 target 名稱和 text 創(chuàng)建一條注釋。 如果
insert_pis為真值,這還會將其添加到樹結(jié)構(gòu)中。3.8 新版功能.
此外,自定義的
TreeBuilder對象還提供了以下方法:- doctype(name, pubid, system)?
處理一條 doctype 聲明。 name 為 doctype 名稱。 pubid 為公有標識。 system 為系統(tǒng)標識。 此方法不存在于默認的
TreeBuilder類中。3.2 新版功能.
- start_ns(prefix, uri)?
在定義了
start()回調(diào)的打開元素的該回調(diào)被調(diào)用之前,當解析器遇到新的命名空間聲明時都會被調(diào)用。 prefix 對于默認命名空間為''或者在其他情況下為被聲明的命名空間前綴名稱。 uri 是命名空間 URI。3.8 新版功能.
- end_ns(prefix)?
在聲明了命名空間前綴映射的元素的
end()回調(diào)之后被調(diào)用,附帶超出作用域的 prefix 的名稱。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)?
C14N 2.0 寫入器。 其參數(shù)與
canonicalize()函數(shù)的相同。 這個類并不會構(gòu)建樹結(jié)構(gòu)而是使用 write 函數(shù)將回調(diào)事件直接轉(zhuǎn)換為序列化形式。3.8 新版功能.
XMLParser對象?
- class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)?
這個類是此模塊的低層級構(gòu)建單元。 它使用
xml.parsers.expat來實現(xiàn)高效、基于事件的 XML 解析。 它可以通過feed()方法增量式地收受 XML 數(shù)據(jù),并且解析事件會被轉(zhuǎn)換為推送式 API —— 通過在 target 對象上發(fā)起對回調(diào)的調(diào)用。 如果省略 target,則會使用標準的TreeBuilder。 如果給出了 encoding 1 ,該值將覆蓋在 XML 文件中指定的編碼格式。在 3.8 版更改: 所有形參現(xiàn)在都是 僅限關(guān)鍵字形參。 html 參數(shù)不再受支持。
- close()?
結(jié)束向解析器提供數(shù)據(jù)。 返回調(diào)用在構(gòu)造期間傳入的 target 的
close()方法的結(jié)果;在默認情況下,這是最高層級的文檔元素。
- feed(data)?
將數(shù)據(jù)送入解析器。 data 是編碼后的數(shù)據(jù)。
XMLParser.feed()會為每個打開的標記調(diào)用 target 的start(tag, attrs_dict)方法,為每個關(guān)閉的標記調(diào)用它的end(tag)方法,并通過data(data)方法來處理數(shù)據(jù)。 有關(guān)更多受支持的回調(diào)方法,請參閱TreeBuilder類。XMLParser.close()會調(diào)用 target 的close()方法。XMLParser不僅僅可被用來構(gòu)建樹結(jié)構(gòu)。 下面是一個統(tǒng)計 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)?
適用于非阻塞應用程序的拉取式解析器。 它的輸入側(cè) API 與
XMLParser的類似,但不是向回調(diào)目標推送調(diào)用,XMLPullParser會收集一個解析事件的內(nèi)部列表并讓用戶來讀取它。 events 是要報告的事件序列。 受支持的事件字符串有"start","end","comment","pi","start-ns"和"end-ns"("ns" 事件被用于獲取詳細的命名空間信息)。 如果 events 被省略,則只報告"end"事件。- feed(data)?
將給定的字節(jié)數(shù)據(jù)送入解析器。
- close()?
通知解析器數(shù)據(jù)流已終結(jié)。 不同于
XMLParser.close(),此方法總是返回None。 當解析器被關(guān)閉時任何還未被獲取的事件仍可通過read_events()被讀取。
- read_events()?
返回包含在送入解析器的數(shù)據(jù)中遇到的事件的迭代器。 此迭代器會產(chǎn)生
(event, elem)對,其中 event 是代表事件類型的字符串 (例如"end") 而 elem 是遇到的Element對象,或者以下的其他上下文值。start,end: 當前元素。comment,pi: 當前注釋 / 處理指令start-ns: 一個指定所聲明命名空間映射的元組(prefix, uri)。end-ns:None(這可能在未來版本中改變)
在之前對
read_events()的調(diào)用中提供的事件將不會被再次產(chǎn)生。 事件僅當它們從迭代器中被取出時才會在內(nèi)部隊列中被消費,因此多個讀取方對獲取自read_events()的迭代器進行平行迭代將產(chǎn)生無法預料的結(jié)果。
備注
XMLPullParser只會確保當發(fā)出 "start" 事件時看到了開始標記的 ">" 字符,因而在這個點上屬性已被定義,但文本內(nèi)容和末尾屬性還未被定義。 這同樣適用于元素的下級;它們可能存在也可能不存在。如果你需要已完全填充的元素,請改為查找 "end" 事件。
3.4 新版功能.
在 3.8 版更改: 增加了
comment和pi事件。
異常?
- class xml.etree.ElementTree.ParseError?
XML 解析器錯誤,由此模塊中的多個解析方法在解析失敗時引發(fā)。 此異常的實例的字符串表示將包含用戶友好的錯誤消息。 此外,它將具有下列可用屬性:
- code?
來自外部解析器的數(shù)字錯誤代碼。 請參閱
xml.parsers.expat的文檔查看錯誤代碼列表及它們的含義。
- position?
一個包含 line, column 數(shù)值的元組,指明錯誤發(fā)生的位置。
備注
- 1(1,2,3,4)
包括在 XML 輸出中的編碼格式字符串應當符合適當?shù)臉藴省?例如 "UTF-8" 是有效的,但 "UTF8" 是無效的。 請參閱 https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl 和 https://www.iana.org/assignments/character-sets/character-sets.xhtml。