網(wǎng)站首頁(yè) 編程語(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
相關(guān)推薦
- 2023-01-12 C語(yǔ)言技巧提升之回調(diào)函數(shù)的掌握_C 語(yǔ)言
- 2022-10-23 C#各種異常處理方式總結(jié)_C#教程
- 2022-10-22 PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng)_PostgreSQL
- 2022-06-25 Gitlab-runner+Docker實(shí)現(xiàn)自動(dòng)部署SpringBoot項(xiàng)目_docker
- 2023-04-01 sqlserver字符串拼接的實(shí)現(xiàn)_MsSql
- 2022-10-01 Iptables防火墻limit模塊擴(kuò)展匹配規(guī)則詳解_安全相關(guān)
- 2022-07-13 卸載Kafka導(dǎo)致的broker id前后不一致,Zookeeper側(cè)清理殘留數(shù)據(jù)指導(dǎo)
- 2022-03-23 Android?app啟動(dòng)圖適配方法實(shí)例_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支