面試官問我:如何在 Python 中解析和修改 XML

abcjob發表於2021-09-11

摘要:我們經常需要解析用不同語言編寫的資料。Python提供了許多庫來解析或拆分用其他語言編寫的資料。在此 Python XML 解析器教程中,您將學習如何使用 Python 解析 XML。

本文分享自華為雲社群《從零開始學python | 如何在 Python 中解析和修改 XML?》,原文作者:Yuchuan。

我們經常需要解析用不同語言編寫的資料。Python提供了許多庫來解析或拆分用其他語言編寫的資料。在此 Python XML 解析器教程中,您將學習如何使用 Python 解析 XML。

以下是本教程中涵蓋的所有主題:

What is XML?
Python XML Parsing Modules
xml.etree.ElementTree Module

  • Using parse() function
  • Using fromstring() function
  • Finding Elements of Interest
  • Modifying XML files
  • Adding to XML
  • Deleting from XML

xml.dom.minidom Module

  • Using parse() function
  • Using fromString() function
  • Finding Elements of Interest

讓我們開始吧。:)

什麼是 XML?

XML 代表可擴充套件標記語言。它在外觀上類似於HTML,但 XML 用於資料表示,而 HTML 用於定義正在使用的資料。XML 專門設計用於在客戶端和伺服器之間來回傳送和接收資料。看看下面的例子:

例子:

<? xml version ="1.0" encoding ="UTF-8" ?>
 <metadata>
 <food>
     <item name ="breakfast" > Idly </item>
     <price> $2.5 </price>
     <description>
   兩個 idly's with chutney
    < /description>
     <calories> 553 </calories>
 </food>
 <food>
     <item name ="breakfast" > Paper Dosa </item>
     <price> $2.7 </price>
     <
        <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>
    藏紅花甜拉瓦
    </description>
     <calories> 950 </calories>
 </食物>
 </後設資料>

上面的示例顯示了我命名為“Sample.xml”的檔案的內容,我將在此 Python XML 解析器教程中為所有即將推出的示例使用相同的內容。

Python XML 解析模組

Python允許使用兩個模組解析這些 XML 文件,即 xml.etree.ElementTree 模組和 Minidom(最小 DOM 實現)。解析意味著從檔案中讀取資訊並通過識別該特定 XML 檔案的部分將其拆分為多個部分。讓我們進一步瞭解如何使用這些模組來解析 XML 資料。

xml.etree.ElementTree 模組:

該模組幫助我們在樹結構中格式化 XML 資料,這是分層資料的最自然表示。元素型別允許在記憶體中儲存分層資料結構,並具有以下屬性:

面試官問我:如何在 Python 中解析和修改 XML

ElementTree 是一個包裝元素結構並允許與 XML 相互轉換的類。現在讓我們嘗試使用python 模組解析上述 XML 檔案。

有兩種使用“ElementTree”模組解析檔案的方法。第一個是使用parse() 函式,第二個是fromstring() 函式。parse() 函式解析作為檔案提供的 XML 文件,而 fromstring 解析作為字串提供的 XML,即在三引號內。

使用 parse() 函式:

如前所述,該函式採用檔案格式的 XML 來解析它。看下面的例子:

例子:

import xml.etree.ElementTree as ET
mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

如您所見,您需要做的第一件事是匯入 xml.etree.ElementTree 模組。然後, parse() 方法解析“Sample.xml”檔案。getroot() 方法返回“Sample.xml”的根元素。

執行上述程式碼時,您不會看到返回的輸出,但不會出現表明程式碼已成功執行的錯誤。要檢查根元素,您可以簡單地使用 print 語句,如下所示:

例子:

import xml.etree.ElementTree as ET
mytree = ET.parse('sample.xml')
myroot = mytree.getroot()
print(myroot)

輸出:    <元素'後設資料'在0x033589F0>

上面的輸出表明我們的 XML 文件中的根元素是“後設資料”。

使用 fromstring() 函式:

您還可以使用 fromstring() 函式來解析您的字串資料。如果要執行此操作,請將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)

輸出:  後設資料

您還可以通過指定要在輸出中看到的字串部分來對標籤字串輸出進行切片。

例子:

print(myroot.tag[0:4])

輸出:  元

如前所述,標籤也可以具有字典屬性。要檢查根標記是否具有任何屬性,您可以使用“attrib”物件,如下所示:

例子:

print(myroot.attrib)

輸出: {}

如您所見,輸出是一個空字典,因為我們的根標籤沒有屬性。

尋找感興趣的元素:

根也由子標籤組成。要檢索根標記的子項,您可以使用以下命令:

例子:

print(myroot[0].tag)

輸出:食物

現在,如果要檢索根的所有第一個子標籤,可以使用 for 迴圈迭代它,如下所示:

例子:

for x in myroot[0]:
     print(x.tag, x.attrib)

輸出:

item {'name': 'breakfast'}
價格 {}
描述 {}
卡路里 {}

返回的所有專案都是食物的子屬性和標籤。

要使用 ElementTree 將文字從 XML 中分離出來,您可以使用 text 屬性。例如,如果我想檢索有關第一個食品的所有資訊,我應該使用以下程式碼:

例子:

for x in myroot[0]:
        print(x.text)

輸出:

懶懶地
$ 2.5
兩悠閒地與酸辣醬的
553

可以看到,第一項的文字資訊已經作為輸出返回了。現在,如果您想顯示具有特定價格的所有商品,您可以使用 get() 方法。此方法訪問元素的屬性。

例子:

for x in myroot.findall('food'):
    item =x.find('item').text
    price = x.find('price').text
    print(item, price)

輸出:

Idly $2.5
Paper Dosa $2.7
Upma $3.65
Bisi Bele Bath $4.50
Kesari Bath $1.95

上面的輸出顯示了所有必需的專案以及每個專案的價格。使用 ElementTree,您還可以修改 XML 檔案。

修改 XML 檔案:

可以操作 XML 檔案中的元素。為此,您可以使用 set() 函式。讓我們首先看看如何向 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() 函式幫助建立一個新的 xml 檔案並將更新的輸出寫入相同的檔案。但是,您也可以使用相同的功能修改原始檔案。執行完上述程式碼後,您將能夠看到已建立具有更新結果的新檔案。

set()-Python XML解析教程-Edureka

 

上圖顯示了對我們食品的修改描述。要新增新的子標籤,您可以使用 SubElement() 方法。例如,如果您想在第一項 Idly 中新增一個新的專業標籤,您可以執行以下操作:

例子:

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')

輸出:

SubElement-Python XML解析教程-Edureka

如您所見,在第一個食品標籤下新增了一個新標籤。通過在 [] 括號內指定下標,您可以在任何地方新增標籤。現在讓我們看一下如何使用此模組刪除專案。

從 XML 中刪除:

要使用 ElementTree 刪除屬性或子元素,您可以使用 pop() 方法。此方法將刪除使用者不需要的所需屬性或元素。

例子:

myroot[0][0].attrib.pop('name', None)
 
# create a new XML file with the results
mytree.write('output5.xml')

輸出:

pop-Python XML 解析教程-Edureka

上圖顯示name屬性已從item標記中刪除。要刪除完整的標籤,您可以使用相同的 pop() 方法,如下所示:

例子:

myroot[0].remove(myroot[0][0])
mytree.write('output6.xml')

輸出:

elementpop-Python XML解析教程-Edureka

輸出顯示食品標籤的第一個子元素已被刪除。如果要刪除所有標籤,可以使用 clear() 函式,如下所示:

例子:

myroot[0].clear()
mytree.write('output7.xml')

輸出:

執行上述程式碼時,food 標籤的第一個子標籤將被完全刪除,包括所有子標籤。到這裡為止,我們一直在使用這個 Python XML 解析器教程中的 xml.etree.ElementTree 模組。現在讓我們看看如何使用 Minidom 解析 XML。

xml.dom.minidom模組:

這個模組基本上是由精通DOM(文件物件模組)的人使用的。DOM 應用程式通常首先將 XML 解析為 DOM。在 xml.dom.minidom 中,這可以通過以下方式實現:

使用 parse() 函式:

第一種方法是通過提供要解析的 XML 檔案作為引數來使用 parse() 函式。例如:

例子:

from xml.dom import minidom
p1 = minidom.parse("sample.xml");

執行此操作後,您將能夠拆分 XML 檔案並獲取所需的資料。您還可以使用此函式解析開啟的檔案。

例子:

dat=open('sample.xml')
p2=minidom.parse(dat)

在這種情況下,儲存開啟檔案的變數作為引數提供給解析函式。

使用 parseString() 方法:

當您想要提供要作為字串解析的 XML 時,將使用此方法。

例子:

p3 = minidom.parseString('<myxml>Using<empty/> parseString</myxml>')

您可以使用上述任何一種方法來解析 XML。現在讓我們嘗試使用此模組獲取資料。

尋找感興趣的元素:

在我的檔案被解析後,如果我嘗試列印它,返回的輸出會顯示一條訊息,表明儲存解析資料的變數是 DOM 物件。

例子:

dat=minidom.parse('sample.xml')
print(dat)

輸出:

<xml.dom.minidom.Document 物件在 0x03B5A308>

使用 GetElementByTagName 訪問元素:

例子:

tagname= dat.getElementsByTagName('item')[0]
print(tagname)

如果我嘗試使用 GetElementByTagName 方法獲取第一個元素,我將看到以下輸出:

輸出:

<DOM 元素:0xc6bd00 處的專案>

請注意,只返回了一個輸出,因為為了方便我使用了 [0] 下標,這將在進一步的示例中刪除。

要訪問屬性的值,我必須按如下方式使用 value 屬性:

例子:

dat = minidom.parse('sample.xml')
tagname= dat.getElementsByTagName('item')
print(tagname[0].attributes['name'].value)

輸出:  早餐

要檢索這些標籤中存在的資料,您可以使用 data 屬性,如下所示:

例子:

        
print(tagname[1].firstChild.data)

輸出: 紙 Dosa

您還可以使用value屬性拆分和檢索屬性的值。

例子:

print(items[1].attributes['name'].value)

輸出: 早餐

要列印出我們選單中可用的所有專案,您可以遍歷這些專案並返回所有專案。

例子:

for x in items:
    print(x.firstChild.data)

輸出:

袖手旁觀
紙DOSA
UPMA
碧斯百麗沐浴
Kesari浴

要計算選單上的專案數,您可以使用 len() 函式,如下所示:

例子:

print(len(items))

輸出指定我們的選單包含 5 個專案。

這使我們結束了本 Python XML 解析器教程。我希望你已經清楚地瞭解了一切。

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章