详解在Python程序中解析并修改XML内容的方法

Ryan
Ryan
发布时间:2026-10-12| 2人浏览过
原创

在实际开发中,经常需要动态修改XML格式的配置文件。本文基于Python标准库xml.etree.ElementTree,详细介绍如何通过路径定位、属性匹配等功能,实现XML节点及子节点的增删改查、文本内容更新,并提供完整可运行的代码示例与保存输出方法,帮助开发者快速掌握自动化配置管理技巧。

需求场景与实现思路

在实际运维或软件配置管理中,通常需要以编程方式实时调整XML配置文件。核心诉求包括:

  1. 增加或删除特定的节点(如插件、服务定义)
  2. 增加、删除或修改节点下的属性键值对
  3. 更新特定节点内的文本内容

Python标准库中的 xml.etree.ElementTree 提供了轻量级的DOM树解析能力。通过将XML文件加载为树状结构后,开发者可以利用XPath路径或属性过滤精准定位目标元素,完成增删改操作后再重新序列化写入磁盘。该方案无需额外依赖,适合轻量级配置热更新场景。

完整操作代码

以下脚本封装了常用操作函数,并演示了从读取、定位、修改到输出的完整流程。代码已适配现代Python 3语法规范。

import xml.etree.ElementTree as ET

def read_xml(in_path):
    '''读取并解析xml文件'''
    tree = ET.parse(in_path)
    return tree

def write_xml(tree, out_path):
    '''将xml文件写出,保留声明与编码'''
    tree.write(out_path, encoding="utf-8", xml_declaration=True)

def if_match(node, kv_map):
    '''判断某个节点是否包含所有传入的属性键值'''
    for key, val in kv_map.items():
        if node.get(key) != val:
            return False
    return True

def find_nodes(tree, xpath):
    '''查找满足XPath路径的所有节点'''
    return tree.findall(xpath)

def get_node_by_keyvalue(nodelist, kv_map):
    '''根据属性键值匹配定位节点列表'''
    return [node for node in nodelist if if_match(node, kv_map)]

def change_node_properties(nodelist, kv_map, is_delete=False):
    '''修改/批量增加 或 删除节点的属性'''
    for node in nodelist:
        for key, val in kv_map.items():
            if is_delete:
                if key in node.attrib:
                    del node.attrib[key]
            else:
                node.set(key, val)

def change_node_text(nodelist, text, is_add=False, is_delete=False):
    '''改变、追加 或 清空节点的文本内容'''
    for node in nodelist:
        if is_add:
            node.text += text
        elif is_delete:
            node.text = ""
        else:
            node.text = text

def create_node(tag, property_map, content):
    '''创建带属性与文本的新节点'''
    elem = ET.Element(tag, property_map)
    elem.text = content
    return elem

def add_child_node(parent_node, element):
    '''将新节点添加到父节点下'''
    parent_node.append(element)

def del_node_by_tagkeyvalue(parent_list, tag, kv_map):
    '''通过标签名与属性条件定位子节点并删除'''
    for parent in parent_list:
        for child in parent:  
            if child.tag == tag and if_match(child, kv_map):
                parent.remove(child)

# ================= 主程序执行流 =================
if __name__ == "__main__":
    # 1. 读取源文件
    tree = read_xml("./test.xml")

    # 2. 属性修改
    nodes = find_nodes(tree, "processers/processer")
    target_nodes = get_node_by_keyvalue(nodes, {"name": "BProcesser"})
    change_node_properties(target_nodes, {"age": "1"})
    change_node_properties(target_nodes, {"value": ""}, is_delete=True)

    # 3. 节点新增
    new_child = create_node("person", {"age": "15", "money": "200000"}, "this is the firest content")
    for tn in target_nodes:
        add_child_node(tn, new_child)

    # 4. 删除节点
    del_parents = find_nodes(tree, "processers/services/service")
    del_node_by_tagkeyvalue(del_parents, "chain", {"sequency": "chain1"})

    # 5. 文本修改
    text_targets = get_node_by_keyvalue(
        find_nodes(tree, "processers/services/service/chain"),
        {"sequency": "chain3"}
    )
    change_node_text(text_targets, "new text")

    # 6. 输出结果
    write_xml(tree, "./out.xml")

第1步:读取与解析XML文件

调用 read_xml() 将本地XML文件加载至内存,生成带有层级关系的 ElementTree 对象。此步骤为后续所有DOM树操作提供入口,无需手动关闭句柄,解析过程自动处理字符集转换。

第2步:通过路径与属性定位节点

使用 tree.findall(xpath) 可按相对路径筛选节点。例如 "processers/processer" 会返回所有匹配的子节点。进一步通过 get_node_by_keyvalue() 传入字典映射,精确锁定具备特定属性组合的目标元素,避免误操作相邻兄弟节点。

第3步:增删改节点属性与文本内容

属性操作支持批量写入或安全删除。当 is_delete=True 时,仅清除存在于节点attrib字典中的键,不会引发异常。文本更新分为覆盖、追加与清空三种模式,通过布尔参数控制行为逻辑,确保存量数据不被意外覆盖。

第4步:创建子节点与删除指定节点

新建节点需明确标签名、属性字典及初始文本,随后调用 append() 注入目标父节点。删除操作依赖父节点容器,遍历子元素比对标签名与属性条件后执行 parent.remove(child),符合树形结构的安全移除规范。

第5步:序列化并输出新文件

所有内存树结构调整完毕后,调用 write_xml() 将修改后的树对象导出为独立文件。参数 encoding="utf-8" 保证中文与特殊符号正确转义,xml_declaration=True 维持XML头部声明一致性,便于下游系统解析。

修改结果对照与排错建议

执行上述脚本后,目标XML文件的结构与内容将发生如下变化:

<?xml version='1.0' encoding='utf-8'?>
<framework>
  <processers>
    <processer name="AProcesser" file="lib64/A.so" path="/tmp" />
    <processer name="BProcesser" file="lib64/B.so" age="1">
      <person age="15" money="200000">this is the firest content</person>
    </processer>
    <processers>  
相关标签:

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

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 算法库。