Python使用ElementTree解析XML文件:增删改查完整指南

栗子
栗子
发布时间:2026-10-16| 5人浏览过
原创

本文详细介绍如何利用Python内置的ElementTree库对XML文件进行高效处理。内容涵盖从基础XML结构解析到高级操作,包括使用parse读取文件、通过iter和find系列方法遍历及定位节点,以及利用Element和append实现元素的动态添加与属性修改。适合需要处理配置文件或数据交换格式的开发人员参考。

PYTHON 操作 XML

读取XML文件

在深入代码之前,了解XML的基本结构至关重要。XML(可扩展标记语言)通过标签来组织数据,具有严格的层级关系。

例如,<data> 与 </data> 构成了一对标准的开始与结束标签,用于包裹内部内容。

此外,<property … /> 这种以 /> 结尾的形式也是合法的XML标签写法,它表示该标签没有嵌套的子节点内容,属于自闭合标签的简写形式。

标签可以包含属性,如 name=“cat”,其中 name 是 <data> 标签的一个属性名,而 cat 则是该属性的具体值。

标签内部还可以包含文本内容,例如 description here … 是 <data> 标签的内容部分,这里展示了一段纯文本。当然,内容部分也可以嵌套其他XML元素,形成复杂的树状结构。

<data name="cat" num="10"> description here ... </data>

<property value="node" />

<country name="china">
	<province name="beijing">
		<school name="the sunshine school" />
	</province>
</country>

为了演示后续操作,我们需要准备一个名为 demo.xml 的示例文件。

<data>
    <teacher name="Albert">
        <birthday>1980</birthday>
        <gender>male</gender>
        <subject>Math</subject>
    </teacher>

    <student name="Becky">
        <birthday>2000</birthday>
        <gender>female</gender>
        <hobbies>
            <hobby>skating</hobby>
            <hobby>rocks</hobby>
        </hobbies>
        <exam absence="no">
            <math>90</math>
            <english>90</english>
            <music>95</music>
        </exam>

    </student>
    <student name="Cindy">
        <birthday>2001</birthday>
        <gender>female</gender>
        <hobbies>
            <hobby>reading</hobby>
            <hobby>guitar</hobby>
        </hobbies>
        <exam absence="yes">
        </exam>
    </student>

    <student name="Duke">
        <birthday>2000</birthday>
        <gender>male</gender>
        <hobbies>
            <hobby>football</hobby>
            <hobby>surfing</hobby>
        </hobbies>
        <exam absence="no">
            <math>100</math>
            <english>80</english>
            <music>92</music>
        </exam>
    </student>

</data>

接下来,我们将演示如何读取该XML文件的内容并获取根元素。

# Read the .xml file
tree = ET.parse("demo.xml")
root = tree.getroot()
print(root)

运行上述代码后,控制台将输出结果。

<Element 'data' at 0x102d80cf8>

遍历XML元素

使用 for … in … 循环可以遍历当前元素的所有直接子节点,这对于处理单层结构非常有效。

for n in root:
    # items() returns all <key, value> pairs of the tag
    print(n, n.tag , n.attrib, n.items())

执行遍历代码后,可以看到以下输出结果。

(<Element 'teacher' at 0x1048b9e48>, 'teacher', {'name': 'Albert'}, [('name', 'Albert')]) (<Element 'student' at 0x1048bf0f0>, 'student', {'name': 'Becky'}, [('name', 'Becky')]) (<Element 'student' at 0x1048bf3c8>, 'student', {'name': 'Cindy'}, [('name', 'Cindy')]) (<Element 'student' at 0x1048bf5f8>, 'student', {'name': 'Duke'}, [('name', 'Duke')])

如果需要迭代遍历当前元素的所有子节点(包括子孙节点),可以使用 iter() 方法。

for n in root.iter():
    print(n, n.tag)

使用 iter() 遍历后的结果如下所示。

(<Element 'data' at 0x1052f0cf8>, 'data') (<Element 'teacher' at 0x1052f0e48>, 'teacher') (<Element 'birthday' at 0x1052f0d30>, 'birthday') (<Element 'gender' at 0x1052f6080>, 'gender') (<Element 'subject' at 0x1052f60b8>, 'subject') (<Element 'student' at 0x1052f60f0>, 'student') (<Element 'birthday' at 0x1052f6048>, 'birthday') (<Element 'gender' at 0x1052f6128>, 'gender') (<Element 'hobbies' at 0x1052f6198>, 'hobbies') (<Element 'hobby' at 0x1052f6208>, 'hobby') (<Element 'hobby' at 0x1052f6240>, 'hobby') (<Element 'exam' at 0x1052f62b0>, 'exam') (<Element 'math' at 0x1052f6320>, 'math') (<Element 'english' at 0x1052f6390>, 'english') (<Element 'music' at 0x1052f6400>, 'music') (<Element 'student' at 0x1052f63c8>, 'student') (<Element 'birthday' at 0x1052f6438>, 'birthday') (<Element 'gender' at 0x1052f6470>, 'gender') (<Element 'hobbies' at 0x1052f64a8>, 'hobbies') (<Element 'hobby' at 0x1052f6518>, 'hobby') (<Element 'hobby' at 0x1052f6588>, 'hobby') (<Element 'exam' at 0x1052f65c0>, 'exam') (<Element 'student' at 0x1052f65f8>, 'student') (<Element 'birthday' at 0x1052f6630>, 'birthday') (<Element 'gender' at 0x1052f6668>, 'gender') (<Element 'hobbies' at 0x1052f66a0>, 'hobbies') (<Element 'hobby' at 0x1052f6710>, 'hobby') (<Element 'hobby' at 0x1052f6780>, 'hobby') (<Element 'exam' at 0x1052f67b8>, 'exam') (<Element 'math' at 0x1052f6828>, 'math') (<Element 'english' at 0x1052f6898>, 'english') (<Element 'music' at 0x1052f6908>, 'music')

若希望有选择性地迭代直接子节点,可以结合条件判断或指定标签名进行过滤。

for n in root.iter('teacher'):
    print(n, n.tag)
(<Element 'teacher' at 0x100f29e48>, 'teacher')

查找XML元素

ElementTree 提供了 find 与 findall 方法来定位特定的XML元素,find 返回第一个匹配项,而 findall 返回所有匹配项的列表。

# find the first element
print(root.find('student'))
# find all  elements
print(root.findall('student'))
<Element 'student' at 0x1034300f0>

[<Element 'student' at 0x1034300f0>, <Element 'student' at 0x1034303c8>, <Element 'student' at 0x1034305f8>]

以下是一个具体的查找示例。

for n in root:
    if n.tag == 'student' and n.get('name') == 'Becky':
        exam_node = n.find('exam')
        for subject in exam_node:
            print(subject.tag + " " + subject.text)

执行查找代码后,控制台输出如下结果。

math 90 english 90 music 95

添加XML元素

p = ET.Element(tag_name)

在现有结构中动态添加新元素是常见需求,可以通过创建 Element 对象并追加到父节点来实现。

for n in root:
    if n.tag == 'student' and n.get('name') == 'Cindy':
        exam_node = n.find('exam')
        exam_node.set("absence", "no")
        for subject in ['math', 'music']:
            p = ET.Element(subject)
            p.text = '90'
            exam_node.append(p)

if os.path.exists('new.xml'):
    os.remove('new.xml')
tree.write('new.xml', encoding='utf-8', xml_declaration=True)

添加元素后的XML结构结果如下。

<student name="Cindy"> <birthday>2001</birthday> <gender>female</gender> <hobbies> <hobby>reading</hobby> <hobby>guitar</hobby> </hobbies> <exam absence="no"> <math>90</math><music>90</music></exam> </student>

修改XML元素

除了添加,我们还可以修改现有元素的属性或文本内容,例如更新成绩或添加新的属性字段。

for n in root:
    if n.tag == 'student' and n.get('name') == 'Cindy':
        exam_node = n.find('exam')
        exam_node.set("absence", "no")
        exam_node.set("date", "2022-11-11")
        for subject in ['math', 'music']:
            p = ET.Element(subject)
            p.text = '90'
            exam_node.append(p)

        hobbies_node = n.find('hobbies').findall("hobby")
        hobbies_node[0].text = 'piano'
        p = ET.Element("hobby")
        p.set("old_hobby", 'yes')
        p.text = 'reading'
        n.find('hobbies').remove(hobbies_node[1])
        n.find('hobbies').append(p)

修改操作完成后的XML结构结果如下。

<student name="Cindy"> <birthday>2001</birthday> <gender>female</gender> <hobbies> <hobby>piano</hobby> <hobby old_hobby="yes">reading</hobby></hobbies> <exam absence="no" date="2022-11-11"> <math>90</math><music>90</music></exam> </student>

到此这篇关于Python对XML文件实现增删改查操作的文章就介绍到这了,更多相关Python XML增删改查内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。