Python解析与修改XML:ElementTree与Minidom实战指南
本文详细介绍Python中解析和修改XML文件的两种核心方法:xml.etree.ElementTree与xml.dom.minidom。通过ElementTree,您可以轻松遍历节点、提取文本与属性,并使用set()、SubElement()及pop()方法实现XML内容的增删改。Minidom则提供基于DOM标准的解析方式,适合需要完整文档对象模型操作的场景。
一、什么是XML?
XML(可扩展标记语言)在语法结构上与HTML相似,但用途截然不同:XML专注于数据的存储与传输,而HTML用于网页展示。它被专门设计用于在客户端与服务器之间高效地交换结构化数据。
示例:
<? 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和xml.dom.minidom(最小DOM实现)。解析过程涉及从文件中读取数据,并根据XML结构将其拆解为不同的部分。接下来将深入探讨如何利用这两个模块处理XML数据。
2.1、xml.etree.ElementTree模块
该模块将XML数据格式化为树状结构,这是处理分层数据最自然的方式。Element类型允许在内存中存储这种层级结构,并具备以下关键属性:

ElementTree是一个封装了元素结构的类,支持XML与Python对象之间的相互转换。下面我们将演示如何使用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()方法则返回该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文档。
此外,您还可以使用“tag”属性获取根标签的名称,如下所示:
示例:
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文件并将更新后的结果写入该文件。您也可以使用相同的功能修改原始文件。执行上述代码后,您将看到一个包含更新结果的新文件。

上图显示了对食品描述所做的修改。若要添加新的子标签,可使用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')
输出:

如上所示,在第一个食品标签下成功添加了一个新标签。通过指定下标,您可以在任意位置添加标签。接下来,我们将介绍如何使用此模块删除项目。
从XML中删除:
若需使用ElementTree删除属性或子元素,可使用pop()方法。该方法将删除用户不需要的特定属性或元素。
示例:
myroot[0][0].attrib.pop('name', None)
# create a new XML file with the results
mytree.write('output5.xml')
输出:

上图显示name属性已从item标签中删除。若要删除完整的标签,可使用相同的pop()方法,如下所示:
示例:
myroot[0].remove(myroot[0][0])
mytree.write('output6.xml')
输出:

输出显示食品标签的第一个子元素已被删除。若需删除所有标签,可使用clear()函数,如下所示:
示例:
myroot[0].clear()
mytree.write('output7.xml')
输出:
执行上述代码时,food标签的第一个子标签将被完全删除,包括其所有子标签。至此,我们一直在使用Python XML解析器教程中的xml.etree.ElementTree模块。接下来,让我们看看如何使用Minidom解析XML。
2.2、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解析器教程。希望您已经清楚地了解了所有内容。
以上就是分析如何在Python中解析和修改XML的详细内容,更多关于Python解析和修改XML的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













