日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Python操作XML文件的使用指南_python

作者:周蘿卜 ? 更新時(shí)間: 2022-11-06 編程語(yǔ)言

什么是 XML

XML 是可擴(kuò)展標(biāo)記語(yǔ)言,它在外觀上類似于 HTML,但 XML 用于數(shù)據(jù)表示,而 HTML 用于定義正在使用的數(shù)據(jù)。XML 專門設(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ù)的最自然表示。元素類型允許在內(nèi)存中存儲(chǔ)分層數(shù)據(jù)結(jié)構(gòu),并具有以下屬性:

Property Description
Tag 一個(gè)字符串,表示正在存儲(chǔ)的數(shù)據(jù)類型
Attributes 由存儲(chǔ)為字典的許多屬性組成
Text String 包含需要顯示的信息的文本字符串
Tail String 如有必要,也可以有尾弦
Child Elements 由許多存儲(chǔ)為序列的子元素組成

ElementTree 是一個(gè)封裝元素結(jié)構(gòu)并允許與 XML 相互轉(zhuǎn)換的類,現(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)的文本信息已作為輸出返回。現(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 文件并將更新的輸出寫入該文件,但是也可以使用相同的功能修改原始文件。執(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)目。

原文鏈接:https://mp.weixin.qq.com/s/7neeJxH3NqckdrwTU0QOZA

欄目分類
最近更新