欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python操作XML文件的使用指南

 更新時(shí)間:2022年09月14日 14:51:01   作者:周蘿卜  
我們經(jīng)常需要解析用不同語(yǔ)言編寫(xiě)的數(shù)據(jù),Python?提供了許多第三方庫(kù)來(lái)解析或拆分用其他語(yǔ)言編寫(xiě)的數(shù)據(jù),今天我們來(lái)學(xué)習(xí)下?Python?XML?解析器的相關(guān)功能

什么是 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),并具有以下屬性:

PropertyDescription
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)文章

最新評(píng)論