Python利用ElementTree模塊處理XML的方法詳解
前言
最近因?yàn)楣ぷ鞯男枰谑褂?Python 來發(fā)送 SOAP 請求以測試 Web Service 的性能,由于 SOAP 是基于 XML 的,故免不了需要使用 python 來處理 XML 數(shù)據(jù)。在對比了幾種方案后,最后選定使用 xml.etree.ElementTree 模塊來實(shí)現(xiàn)。
這篇文章記錄了使用 xml.etree.ElementTree 模塊常用的幾個操作,也算是總結(jié)一下,免得以后忘記了。分享出來也方法需要的朋友們參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
概述
對比其他 Python 處理 XML 的方案,xml.etree.ElementTree 模塊(下文我們以 ET 來表示)相對來說比較簡單,接口也較友好。
官方文檔 里面對 ET 模塊進(jìn)行了較為詳細(xì)的描述,總的來說,ET 模塊可以歸納為三個部分:ElementTree類,Element類以及一些操作 XML 的函數(shù)。
XML 可以看成是一種樹狀結(jié)構(gòu),ET 使用ElementTree類來表示整個 XML 文檔,使用Element類來表示 XML 的一個結(jié)點(diǎn)。對整 XML 文檔的操作一般是對ElementTree對象進(jìn)行,而對 XML 結(jié)點(diǎn)的操作一般是對Element對象進(jìn)行。
解析 XML 文件
ET 模塊支持從一個 XML 文件構(gòu)造ElementTree對象,例如我們的 XML 文件example.xml內(nèi)容如下(下文會繼續(xù)使用這個 XML 文檔):
<?xml version="1.0" encoding="utf-8"?> <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> </data>
可以使用 ET 模塊的parse()函數(shù)來從指定的 XML 文件構(gòu)造一個ElementTree對象:
import xml.etree.ElementTree as ET
# 獲取 XML 文檔對象 ElementTree
tree = ET.parse('example.xml')
# 獲取 XML 文檔對象的根結(jié)點(diǎn) Element
root = tree.getroot()
# 打印根結(jié)點(diǎn)的名稱
print root.tag
從 XML 文件構(gòu)造好ElementTree對象后,還可以獲取其結(jié)點(diǎn),或者再繼續(xù)對結(jié)點(diǎn)進(jìn)行進(jìn)一步的操作。
解析 XML 字符串
ET 模塊的fromstring()函數(shù)提供從 XML 字符串構(gòu)造一個Element對象的功能。
xml_str = ET.tostring(root) print xml_str root = ET.fromstring(xml_str) print root.tag
接著上面的代碼,我們使用 ET 模塊的tostring()函數(shù)來將上面我們構(gòu)造的root對象轉(zhuǎn)化為字符串,然后使用fromstring()函數(shù)重新構(gòu)造一個Element對象,并賦值給root變量,這時root代表整個 XML 文檔的根結(jié)點(diǎn)。
構(gòu)造 XML
如果我們需要構(gòu)造 XML 文檔,可以使用 ET 模塊的 Element類以及SubElement()函數(shù)。
可以使用Element類來生成一個Element對象作為根結(jié)點(diǎn),然后使用ET.SubElement()函數(shù)生成子結(jié)點(diǎn)。
a = ET.Element('a')
b = ET.SubElement(a, 'b')
b.text = 'leehao.me'
c = ET.SubElement(a, 'c')
c.attrib['greeting'] = 'hello'
d = ET.SubElement(a, 'd')
d.text = 'www.leehao.me'
xml_str = ET.tostring(a, encoding='UTF-8')
print xml_str
輸出:
<?xml version='1.0' encoding='UTF-8'?> <a><b>leehao.me</b><c greeting="hello" /><d>www.leehao.me</d></a>
如果需要輸出到文件中,可以繼續(xù)使用ElementTree.write()方法來處理:
# 先構(gòu)造一個 ElementTree 以便使用其 write 方法
tree = ET.ElementTree(a)
tree.write('a.xml', encoding='UTF-8')
執(zhí)行后,便會生成一個 XML 文件a.xml:
<?xml version='1.0' encoding='UTF-8'?> <a><b>leehao.me</b><c greeting="hello" /><d>www.leehao.me</d></a>
XML 結(jié)點(diǎn)的查找與更新
1. 查找 XML 結(jié)點(diǎn)
Element類提供了Element.iter()方法來查找指定的結(jié)點(diǎn)。Element.iter()會遞歸查找所有的子結(jié)點(diǎn),以便查找到所有符合條件的結(jié)點(diǎn)。
# 獲取 XML 文檔對象 ElementTree
tree = ET.parse('example.xml')
# 獲取 XML 文檔對象的根結(jié)點(diǎn) Element
root = tree.getroot()
# 遞歸查找所有的 neighbor 子結(jié)點(diǎn)
for neighbor in root.iter('neighbor'):
print neighbor.attrib
輸出:
{'direction': 'E', 'name': 'Austria'}
{'direction': 'W', 'name': 'Switzerland'}
{'direction': 'N', 'name': 'Malaysia'}
如果使用Element.findall()或者Element.find()方法,則只會從結(jié)點(diǎn)的直接子結(jié)點(diǎn)中查找,并不會遞歸查找。
for country in root.findall('country'):
rank = country.find('rank').text
name = country.get('name')
print name, rank
輸出:
Liechtenstein 1 Singapore 4
2. 更新結(jié)點(diǎn)
如果需要更新結(jié)點(diǎn)的文本,可以通過直接修改Element.text來實(shí)現(xiàn)。如果需要更新結(jié)點(diǎn)的屬性,可以通過直接修改Element.attrib來實(shí)現(xiàn)。
對結(jié)點(diǎn)進(jìn)行更新后,可以使用ElementTree.write()方法將更新后的 XML 文檔寫入文件中。
# 獲取 XML 文檔對象 ElementTree
tree = ET.parse('example.xml')
# 獲取 XML 文檔對象的根結(jié)點(diǎn) Element
root = tree.getroot()
for rank in root.iter('rank'):
new_rank = int(rank.text) + 1
rank.text = str(new_rank)
rank.attrib['updated'] = 'yes'
tree.write('output.xml', encoding='UTF-8')
新生成的output.xml文件以下:
<?xml version='1.0' encoding='UTF-8'?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> </data>
對比example.xml文件,可以看到output.xml文件已更新。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
參考資料
相關(guān)文章
python線程池threadpool實(shí)現(xiàn)篇
這篇文章主要為大家詳細(xì)介紹了python線程池threadpool的實(shí)現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Pandas中把dataframe轉(zhuǎn)成array的方法
下面小編就為大家分享一篇Pandas中把dataframe轉(zhuǎn)成array的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
Python?tkinter實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了Python?tkinter實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
Python+pandas編寫命令行腳本操作excel的tips詳情
這篇文章主要介紹了Python+pandas編寫命令行腳本操作excel的tips詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-07-07
基于Pytorch實(shí)現(xiàn)分類器的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何基于Pytorch實(shí)現(xiàn)兩個分類器:?softmax分類器和感知機(jī)分類器,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-04-04
Python Flask 和 Django 的區(qū)別與適用場景示例分析
Flask和Django是兩個流行的Python Web框架,但設(shè)計(jì)哲學(xué)、功能和用法有很大區(qū)別,Flask是一個輕量級框架,簡單靈活,適合小型項(xiàng)目和快速原型開發(fā),本文給大家介紹Python Flask 和 Django 的區(qū)別與適用場景示例分析,感興趣的朋友跟隨小編一起看看吧2024-10-10
python實(shí)現(xiàn)簡單聊天應(yīng)用 python群聊和點(diǎn)對點(diǎn)均實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡單聊天應(yīng)用,python群聊和點(diǎn)對點(diǎn)均實(shí)現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09

