Python操作XML文件的使用指南
什么是 XML
XML 是可擴(kuò)展標(biāo)記語(yǔ)言,它在外觀上類(lèi)似于 HTML,但 XML 用于數(shù)據(jù)表示,而 HTML 用于定義正在使用的數(shù)據(jù)。XML 專門(mén)設(shè)計(jì)用于在客戶端和服務(wù)器之間來(lái)回發(fā)送和接收數(shù)據(jù)??纯聪旅娴睦樱?/p>
<?xml?version="1.0"?encoding="UTF-8"?> <metadata> <food> ????<item?name="breakfast">Idly</item> ????<price>$2.5</price> ????<description> ???Two?idly's?with?chutney ???</description> ????<calories>553</calories> </food> <food> ????<item?name="breakfast">Paper?Dosa</item> ????<price>$2.7</price> ????<description> ????Plain?paper?dosa?with?chutney ????</description> ????<calories>700</calories> </food> <food> ????<item?name="breakfast">Upma</item> ????<price>$3.65</price> ????<description> ????Rava?upma?with?bajji ????</description> ????<calories>600</calories> </food> <food> ????<item?name="breakfast">Bisi?Bele?Bath</item> ????<price>$4.50</price> ????<description> ???Bisi?Bele?Bath?with?sev ????</description> ????<calories>400</calories> </food> <food> ????<item?name="breakfast">Kesari?Bath</item> ????<price>$1.95</price> ????<description> ????Sweet?rava?with?saffron ????</description> ????<calories>950</calories> </food> </metadata>
上面的示例顯示了命名為“Sample.xml”的文件的內(nèi)容,后面的代碼示例都會(huì)基于此 XML 例子來(lái)進(jìn)行。
Python XML 解析模塊
Python 允許使用兩個(gè)模塊解析這些 XML 文檔,即 xml.etree.ElementTree 模塊和 Minidom(最小 DOM 實(shí)現(xiàn))。解析意味著從文件中讀取信息,并通過(guò)識(shí)別特定 XML 文件的各個(gè)部分將其拆分為多個(gè)片段。讓我們進(jìn)一步了解如何使用這些模塊來(lái)解析 XML 數(shù)據(jù)。
xml.etree.ElementTree 模塊
該模塊幫助我們將 XML 數(shù)據(jù)格式化為樹(shù)結(jié)構(gòu),這是分層數(shù)據(jù)的最自然表示。元素類(lèi)型允許在內(nèi)存中存儲(chǔ)分層數(shù)據(jù)結(jié)構(gòu),并具有以下屬性:
| Property | Description |
|---|---|
| Tag | 一個(gè)字符串,表示正在存儲(chǔ)的數(shù)據(jù)類(lèi)型 |
| Attributes | 由存儲(chǔ)為字典的許多屬性組成 |
| Text String | 包含需要顯示的信息的文本字符串 |
| Tail String | 如有必要,也可以有尾弦 |
| Child Elements | 由許多存儲(chǔ)為序列的子元素組成 |
ElementTree 是一個(gè)封裝元素結(jié)構(gòu)并允許與 XML 相互轉(zhuǎn)換的類(lèi),現(xiàn)在讓我們嘗試使用 python 模塊解析上述 XML 文件。
有兩種方法可以使用ElementTree模塊解析文件。
第一個(gè)是使用 parse() 函數(shù),第二個(gè)是 fromstring() 函數(shù)。 parse() 函數(shù)解析作為文件提供的 XML 文檔,而 fromstring 在作為字符串提供時(shí)解析 XML,即在三引號(hào)內(nèi)。
使用 parse() 函數(shù)
如前所述,該函數(shù)采用文件格式的 XML 進(jìn)行解析,看看下面的例子:
import?xml.etree.ElementTree?as?ET
mytree?=?ET.parse('sample.xml')
myroot?=?mytree.getroot()
我們需要做的第一件事是導(dǎo)入 xml.etree.ElementTree 模塊,然后使用 parse() 方法解析“Sample.xml”文件,getroot() 方法返回“Sample.xml”的根元素。
當(dāng)執(zhí)行上述代碼時(shí),我們不會(huì)看到返回的輸出,但只要不會(huì)有錯(cuò)誤就表明代碼已成功執(zhí)行。要檢查根元素,可以簡(jiǎn)單地使用 print 語(yǔ)句,如下所示:
import?xml.etree.ElementTree?as?ET
mytree?=?ET.parse('sample.xml')
myroot?=?mytree.getroot()
print(myroot)
Output:
<Element ‘metadata’ at 0x033589F0>
上面的輸出表明我們的 XML 文檔中的根元素是“元數(shù)據(jù)”。
使用 fromstring() 函數(shù)
我們還可以使用 fromstring() 函數(shù)來(lái)解析字符串?dāng)?shù)據(jù),我們需要將 XML 作為三引號(hào)內(nèi)的字符串傳遞,如下所示:
import?xml.etree.ElementTree?as?ET data='''<?xml?version="1.0"?encoding="UTF-8"?> <metadata> <food> ????<item?name="breakfast">Idly</item> ????<price>$2.5</price> ????<description> ???Two?idly's?with?chutney ???</description> ????<calories>553</calories> </food> </metadata> ''' myroot?=?ET.fromstring(data) #print(myroot) print(myroot.tag)
上面的代碼將返回與前一個(gè)相同的輸出,用作字符串的 XML 文檔只是“Sample.xml”的一部分,已將其用于提高可見(jiàn)性,也可以使用完整的 XML 文檔。
還可以使用“標(biāo)簽”對(duì)象檢索根標(biāo)簽,如下所示:
print(myroot.tag)
Output:
metadata
還可以通過(guò)僅指定要在輸出中看到的字符串部分來(lái)對(duì)標(biāo)記字符串輸出進(jìn)行切片。
print(myroot.tag[0:4])
Output:
meta
如前所述,標(biāo)簽也可以具有字典屬性。要檢查根標(biāo)簽是否有任何屬性,您可以使用“attrib”對(duì)象,如下所示:
print(myroot.attrib)
Output:
{}
可以看到,輸出是一個(gè)空字典,因?yàn)槲覀兊母鶚?biāo)簽沒(méi)有屬性。
尋找感興趣的元素
根也由子標(biāo)簽組成,要檢索根標(biāo)簽的子標(biāo)簽,可以使用以下命令:
print(myroot[0].tag)
Output:
food
現(xiàn)在,如果要檢索根的所有第一個(gè)子標(biāo)記,可以使用 for 循環(huán)對(duì)其進(jìn)行迭代,如下所示:
for?x?in?myroot[0]: ?????print(x.tag,?x.attrib)
Output:
item {‘name’: ‘breakfast’}
price {}
description {}
calories {}
返回的所有項(xiàng)目都是食物的子屬性和標(biāo)簽。
要使用 ElementTree 從 XML 中分離出文本,可以使用 text 屬性。 例如,如果想檢索關(guān)于第一個(gè)食物的所有信息,應(yīng)該使用以下代碼:
for?x?in?myroot[0]: ????????print(x.text)
Output:
Idly
$2.5
Two idly’s with chutney
553
可以看出,第一項(xiàng)的文本信息已作為輸出返回?,F(xiàn)在如果想以特定價(jià)格顯示所有商品,可以使用 get() 方法,此方法訪問(wèn)元素的屬性。
for?x?in?myroot.findall('food'):
????item?=x.find('item').text
????price?=?x.find('price').text
????print(item,?price)
Output:
Idly $2.5
Paper Dosa $2.7
Upma $3.65
Bisi Bele Bath $4.50
Kesari Bath $1.95
上面的輸出顯示了所有必需的項(xiàng)目以及每個(gè)項(xiàng)目的價(jià)格,使用 ElementTree,還可以修改 XML 文件。
修改 XML 文件
我們的 XML 文件中的元素是可以被操縱的,為此,可以使用 set() 函數(shù)。讓我們先來(lái)看看如何在 XML 中添加一些東西。
添加到 XML:
以下示例顯示了如何在項(xiàng)目描述中添加內(nèi)容。
for?description?in?myroot.iter('description'):
?????new_desc?=?str(description.text)+'wil?be?served'
?????description.text?=?str(new_desc)
?????description.set('updated',?'yes')
?
mytree.write('new.xml')
write() 函數(shù)有助于創(chuàng)建一個(gè)新的 xml 文件并將更新的輸出寫(xiě)入該文件,但是也可以使用相同的功能修改原始文件。執(zhí)行上述代碼后,將能夠看到已創(chuàng)建一個(gè)包含更新結(jié)果的新文件。

上圖顯示了我們食品項(xiàng)目的修改描述。要添加新的子標(biāo)簽,可以使用 SubElement() 方法。例如,如果想在第一項(xiàng) Idly 中添加新的專業(yè)標(biāo)簽,可以執(zhí)行以下操作:
ET.SubElement(myroot[0],?'speciality')
for?x?in?myroot.iter('speciality'):
?????new_desc?=?'South?Indian?Special'
?????x.text?=?str(new_desc)
?
mytree.write('output5.xml')
Output:

就像我們所見(jiàn)到的,在第一個(gè)食物標(biāo)簽下添加了一個(gè)新標(biāo)簽。可以通過(guò)在 [] 括號(hào)內(nèi)指定下標(biāo)來(lái)在任意位置添加標(biāo)簽。
下面讓我們看看如何使用這個(gè)模塊刪除項(xiàng)目。
從 XML 中刪除:
要使用 ElementTree 刪除屬性或子元素,可以使用 pop() 方法,此方法將刪除用戶不需要的所需屬性或元素。
myroot[0][0].attrib.pop('name',?None)
?
#?create?a?new?XML?file?with?the?results
mytree.write('output5.xml')
Output:

上圖顯示 name 屬性已從 item 標(biāo)記中刪除。要?jiǎng)h除完整的標(biāo)簽,可以使用相同的 pop() 方法,如下所示:
myroot[0].remove(myroot[0][0])
mytree.write('output6.xml')
Output:

輸出顯示食品標(biāo)簽的第一個(gè)子元素已被刪除。如果要?jiǎng)h除所有標(biāo)簽,可以使用 clear() 函數(shù),如下所示:
myroot[0].clear()
mytree.write('output7.xml')
執(zhí)行上述代碼時(shí),food 標(biāo)簽的第一個(gè)子標(biāo)簽將被完全刪除,包括所有子標(biāo)簽。
到目前為止,我們一直在使用 Python XML 解析器中的 xml.etree.ElementTree 模塊。現(xiàn)在讓我們看看如何使用 Minidom 解析 XML。
xml.dom.minidom Module
該模塊基本上是由精通DOM(文檔對(duì)象模塊)的人使用的,DOM 應(yīng)用程序通常首先將 XML 解析為 DOM。在 xml.dom.minidom 中,可以通過(guò)以下方式實(shí)現(xiàn)
使用 parse() 函數(shù):
第一種方法是通過(guò)提供要解析的 XML 文件作為參數(shù)來(lái)使用 parse()函數(shù)。例如:
from?xml.dom?import?minidom
p1?=?minidom.parse("sample.xml")
執(zhí)行此操作后,將能夠拆分 XML 文件并獲取所需的數(shù)據(jù)。還可以使用此函數(shù)解析打開(kāi)的文件。
dat=open('sample.xml')
p2=minidom.parse(dat)
在這種情況下,存儲(chǔ)打開(kāi)文件的變量作為參數(shù)提供給 parse 函數(shù)。
使用 parseString() 方法:
當(dāng)我們想要提供要作為字符串解析的 XML 時(shí)使用此方法。
p3?=?minidom.parseString('<myxml>Using<empty/>?parseString</myxml>')
可以使用上述任何方法解析 XML,現(xiàn)在讓我們嘗試使用這個(gè)模塊獲取數(shù)據(jù)
尋找感興趣的元素
在我的文件被解析后,如果我們嘗試打印它,返回的輸出會(huì)顯示一條消息,即存儲(chǔ)解析數(shù)據(jù)的變量是 DOM 的對(duì)象。
dat=minidom.parse('sample.xml')
print(dat)
Output:
<xml.dom.minidom.Document object at 0x03B5A308>
使用 GetElementsByTagName 訪問(wèn)元素
tagname=?dat.getElementsByTagName('item')[0]
print(tagname)
如果我們嘗試使用 GetElementByTagName 方法獲取第一個(gè)元素,我將看到以下輸出:
<DOM Element: item at 0xc6bd00>
請(qǐng)注意,只返回了一個(gè)輸出,因?yàn)闉榉奖闫鹨?jiàn),這里使用了 [0] 下標(biāo),這將在進(jìn)一步的示例中被刪除。
要訪問(wèn)屬性的值,我們將不得不使用 value 屬性,如下所示:
dat?=?minidom.parse('sample.xml')
tagname=?dat.getElementsByTagName('item')
print(tagname[0].attributes['name'].value)
Output:
breakfast
要檢索這些標(biāo)簽中存在的數(shù)據(jù),可以使用 data 屬性,如下所示:
print(tagname[1].firstChild.data)
Output:
Paper Dosa
還可以使用 value 屬性拆分和檢索屬性的值。
print(items[1].attributes['name'].value)
Output:
breakfast
要打印出我們菜單中的所有可用項(xiàng)目,可以遍歷這些項(xiàng)目并返回所有項(xiàng)目。
for?x?in?items: ????print(x.firstChild.data)
Output:
Idly
Paper Dosa
Upma
Bisi Bele Bath
Kesari Bath
要計(jì)算我們菜單上的項(xiàng)目數(shù),可以使用 len() 函數(shù),如下所示:
print(len(items))
Output:
5
輸出指定我們的菜單包含 5 個(gè)項(xiàng)目。
到此這篇關(guān)于Python操作XML文件的使用指南的文章就介紹到這了,更多相關(guān)Python操作XML內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python內(nèi)置函數(shù)ord()的實(shí)現(xiàn)示例
ord()函數(shù)是用于返回字符的Unicode碼點(diǎn),適用于處理文本和國(guó)際化應(yīng)用,它只能處理單個(gè)字符,超過(guò)一字符或非字符串類(lèi)型會(huì)引發(fā)TypeError,示例代碼展示了如何使用ord()進(jìn)行字符轉(zhuǎn)換和比較2024-09-09
Python isinstance判斷對(duì)象類(lèi)型
Python中判度對(duì)象類(lèi)型方法非常簡(jiǎn)單,不需要像別的語(yǔ)言一樣使用如下的判斷方法2008-09-09
Ubuntu 20.04安裝Pycharm2020.2及鎖定到任務(wù)欄的問(wèn)題(小白級(jí)操作)
這篇文章主要介紹了Ubuntu 20.04安裝Pycharm2020.2及鎖定到任務(wù)欄的問(wèn)題,本教程給大家講解的很詳細(xì),非常適合小白級(jí)操作,需要的朋友可以參考下2020-10-10
Python基礎(chǔ)學(xué)習(xí)之簡(jiǎn)單理解函數(shù)
學(xué)了函數(shù)才算是能推動(dòng)python的門(mén)了,今天就帶大家了解一下函數(shù)的相關(guān)知識(shí),文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
使用pycharm進(jìn)行繪圖,圖片無(wú)法顯示的解決
這篇文章主要介紹了使用pycharm進(jìn)行繪圖,圖片無(wú)法顯示的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
關(guān)于Series的index的方法和屬性使用說(shuō)明
這篇文章主要介紹了關(guān)于Series的index的方法和屬性使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06

