Python操作XML文件的使用指南
什么是 XML
XML 是可擴展標記語言,它在外觀上類似于 HTML,但 XML 用于數(shù)據(jù)表示,而 HTML 用于定義正在使用的數(shù)據(jù)。XML 專門設計用于在客戶端和服務器之間來回發(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”的文件的內容,后面的代碼示例都會基于此 XML 例子來進行。
Python XML 解析模塊
Python 允許使用兩個模塊解析這些 XML 文檔,即 xml.etree.ElementTree 模塊和 Minidom(最小 DOM 實現(xiàn))。解析意味著從文件中讀取信息,并通過識別特定 XML 文件的各個部分將其拆分為多個片段。讓我們進一步了解如何使用這些模塊來解析 XML 數(shù)據(jù)。
xml.etree.ElementTree 模塊
該模塊幫助我們將 XML 數(shù)據(jù)格式化為樹結構,這是分層數(shù)據(jù)的最自然表示。元素類型允許在內存中存儲分層數(shù)據(jù)結構,并具有以下屬性:
Property | Description |
---|---|
Tag | 一個字符串,表示正在存儲的數(shù)據(jù)類型 |
Attributes | 由存儲為字典的許多屬性組成 |
Text String | 包含需要顯示的信息的文本字符串 |
Tail String | 如有必要,也可以有尾弦 |
Child Elements | 由許多存儲為序列的子元素組成 |
ElementTree 是一個封裝元素結構并允許與 XML 相互轉換的類,現(xiàn)在讓我們嘗試使用 python 模塊解析上述 XML 文件。
有兩種方法可以使用ElementTree
模塊解析文件。
第一個是使用 parse()
函數(shù),第二個是 fromstring()
函數(shù)。 parse()
函數(shù)解析作為文件提供的 XML 文檔,而 fromstring
在作為字符串提供時解析 XML,即在三引號內。
使用 parse() 函數(shù)
如前所述,該函數(shù)采用文件格式的 XML 進行解析,看看下面的例子:
import?xml.etree.ElementTree?as?ET mytree?=?ET.parse('sample.xml') myroot?=?mytree.getroot()
我們需要做的第一件事是導入 xml.etree.ElementTree 模塊,然后使用 parse()
方法解析“Sample.xml”文件,getroot()
方法返回“Sample.xml”的根元素。
當執(zhí)行上述代碼時,我們不會看到返回的輸出,但只要不會有錯誤就表明代碼已成功執(zhí)行。要檢查根元素,可以簡單地使用 print 語句,如下所示:
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ù)來解析字符串數(shù)據(jù),我們需要將 XML 作為三引號內的字符串傳遞,如下所示:
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)
上面的代碼將返回與前一個相同的輸出,用作字符串的 XML 文檔只是“Sample.xml”的一部分,已將其用于提高可見性,也可以使用完整的 XML 文檔。
還可以使用“標簽”對象檢索根標簽,如下所示:
print(myroot.tag)
Output:
metadata
還可以通過僅指定要在輸出中看到的字符串部分來對標記字符串輸出進行切片。
print(myroot.tag[0:4])
Output:
meta
如前所述,標簽也可以具有字典屬性。要檢查根標簽是否有任何屬性,您可以使用“attrib”對象,如下所示:
print(myroot.attrib)
Output:
{}
可以看到,輸出是一個空字典,因為我們的根標簽沒有屬性。
尋找感興趣的元素
根也由子標簽組成,要檢索根標簽的子標簽,可以使用以下命令:
print(myroot[0].tag)
Output:
food
現(xiàn)在,如果要檢索根的所有第一個子標記,可以使用 for 循環(huán)對其進行迭代,如下所示:
for?x?in?myroot[0]: ?????print(x.tag,?x.attrib)
Output:
item {‘name’: ‘breakfast’}
price {}
description {}
calories {}
返回的所有項目都是食物的子屬性和標簽。
要使用 ElementTree 從 XML 中分離出文本,可以使用 text 屬性。 例如,如果想檢索關于第一個食物的所有信息,應該使用以下代碼:
for?x?in?myroot[0]: ????????print(x.text)
Output:
Idly
$2.5
Two idly’s with chutney
553
可以看出,第一項的文本信息已作為輸出返回?,F(xiàn)在如果想以特定價格顯示所有商品,可以使用 get()
方法,此方法訪問元素的屬性。
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
上面的輸出顯示了所有必需的項目以及每個項目的價格,使用 ElementTree,還可以修改 XML 文件。
修改 XML 文件
我們的 XML 文件中的元素是可以被操縱的,為此,可以使用 set()
函數(shù)。讓我們先來看看如何在 XML 中添加一些東西。
添加到 XML:
以下示例顯示了如何在項目描述中添加內容。
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)建一個新的 xml 文件并將更新的輸出寫入該文件,但是也可以使用相同的功能修改原始文件。執(zhí)行上述代碼后,將能夠看到已創(chuàng)建一個包含更新結果的新文件。
上圖顯示了我們食品項目的修改描述。要添加新的子標簽,可以使用 SubElement()
方法。例如,如果想在第一項 Idly 中添加新的專業(yè)標簽,可以執(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:
就像我們所見到的,在第一個食物標簽下添加了一個新標簽??梢酝ㄟ^在 []
括號內指定下標來在任意位置添加標簽。
下面讓我們看看如何使用這個模塊刪除項目。
從 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 標記中刪除。要刪除完整的標簽,可以使用相同的 pop()
方法,如下所示:
myroot[0].remove(myroot[0][0]) mytree.write('output6.xml')
Output:
輸出顯示食品標簽的第一個子元素已被刪除。如果要刪除所有標簽,可以使用 clear()
函數(shù),如下所示:
myroot[0].clear() mytree.write('output7.xml')
執(zhí)行上述代碼時,food
標簽的第一個子標簽將被完全刪除,包括所有子標簽。
到目前為止,我們一直在使用 Python XML 解析器中的 xml.etree.ElementTree
模塊?,F(xiàn)在讓我們看看如何使用 Minidom
解析 XML。
xml.dom.minidom Module
該模塊基本上是由精通DOM(文檔對象模塊)的人使用的,DOM 應用程序通常首先將 XML 解析為 DOM。在 xml.dom.minidom 中,可以通過以下方式實現(xiàn)
使用 parse() 函數(shù):
第一種方法是通過提供要解析的 XML 文件作為參數(shù)來使用 parse()
函數(shù)。例如:
from?xml.dom?import?minidom p1?=?minidom.parse("sample.xml")
執(zhí)行此操作后,將能夠拆分 XML 文件并獲取所需的數(shù)據(jù)。還可以使用此函數(shù)解析打開的文件。
dat=open('sample.xml') p2=minidom.parse(dat)
在這種情況下,存儲打開文件的變量作為參數(shù)提供給 parse 函數(shù)。
使用 parseString() 方法:
當我們想要提供要作為字符串解析的 XML 時使用此方法。
p3?=?minidom.parseString('<myxml>Using<empty/>?parseString</myxml>')
可以使用上述任何方法解析 XML,現(xiàn)在讓我們嘗試使用這個模塊獲取數(shù)據(jù)
尋找感興趣的元素
在我的文件被解析后,如果我們嘗試打印它,返回的輸出會顯示一條消息,即存儲解析數(shù)據(jù)的變量是 DOM 的對象。
dat=minidom.parse('sample.xml') print(dat)
Output:
<xml.dom.minidom.Document object at 0x03B5A308>
使用 GetElementsByTagName 訪問元素
tagname=?dat.getElementsByTagName('item')[0] print(tagname)
如果我們嘗試使用 GetElementByTagName
方法獲取第一個元素,我將看到以下輸出:
<DOM Element: item at 0xc6bd00>
請注意,只返回了一個輸出,因為為方便起見,這里使用了 [0]
下標,這將在進一步的示例中被刪除。
要訪問屬性的值,我們將不得不使用 value
屬性,如下所示:
dat?=?minidom.parse('sample.xml') tagname=?dat.getElementsByTagName('item') print(tagname[0].attributes['name'].value)
Output:
breakfast
要檢索這些標簽中存在的數(shù)據(jù),可以使用 data
屬性,如下所示:
print(tagname[1].firstChild.data)
Output:
Paper Dosa
還可以使用 value
屬性拆分和檢索屬性的值。
print(items[1].attributes['name'].value)
Output:
breakfast
要打印出我們菜單中的所有可用項目,可以遍歷這些項目并返回所有項目。
for?x?in?items: ????print(x.firstChild.data)
Output:
Idly
Paper Dosa
Upma
Bisi Bele Bath
Kesari Bath
要計算我們菜單上的項目數(shù),可以使用 len()
函數(shù),如下所示:
print(len(items))
Output:
5
輸出指定我們的菜單包含 5 個項目。
到此這篇關于Python操作XML文件的使用指南的文章就介紹到這了,更多相關Python操作XML內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python內置函數(shù)ord()的實現(xiàn)示例
ord()函數(shù)是用于返回字符的Unicode碼點,適用于處理文本和國際化應用,它只能處理單個字符,超過一字符或非字符串類型會引發(fā)TypeError,示例代碼展示了如何使用ord()進行字符轉換和比較2024-09-09Ubuntu 20.04安裝Pycharm2020.2及鎖定到任務欄的問題(小白級操作)
這篇文章主要介紹了Ubuntu 20.04安裝Pycharm2020.2及鎖定到任務欄的問題,本教程給大家講解的很詳細,非常適合小白級操作,需要的朋友可以參考下2020-10-10