You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否有Python包可将xmltodict字典转为lxml树?附XML构建需求

解决方案

一、只用xmltodict实现目标XML结构

完全可以不用切换到lxml,xmltodict本身支持生成这种混合节点结构,核心是利用列表定义同级异构节点。

假设你的四个action字典分别是action1、action2、action3、action4,可以构造如下根字典:

import xmltodict

action1 = {"@id": 1, "some-nested-stuff": {"@attr1": "string value", "child": True}}
action2 = {"@id": 2, "...": "..."}
action3 = {"@id": 3, "...": "..."}
action4 = {"@id": 4, "...": "..."}

root_dict = {
    "root": [  # root为XML根节点,可根据实际需求替换
        {"action": action1},
        {"action-group": {
            "@groupId": 1,
            "action": [action2, action3]  # 列表生成多个action子节点
        }},
        {"action": action4}
    ]
}

# 生成XML
xml_output = xmltodict.unparse(root_dict, pretty=True, full_document=True)
print(xml_output)

生成的XML会完全符合你的要求:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <action id="1">
        <some-nested-stuff attr1="string value">
            <child>True</child>
        </some-nested-stuff>
    </action>
    <action-group groupId="1">
        <action id="2">
            <...>...</...>
        </action>
        <action id="3">
            <...>...</...>
        </action>
    </action-group>
    <action id="4">
        <...>...</...>
    </action>
</root>

关键要点:

  • 将需要同级排列的不同节点(action、action-group、action)放进同一个列表,作为根节点的值
  • 每个列表元素是单键字典,键对应节点名,值对应节点的结构字典
  • 对于action-group内部的多个action子节点,同样用列表包裹,确保生成多个<action>标签

二、将xmltodict字典转换为lxml树对象

如果确实需要结合lxml操作,最现成的方法是先通过xmltodict生成XML字符串,再用lxml解析:

from lxml import etree
import xmltodict

# 构造字典并生成XML字符串
action1 = {"@id": 1, "some-nested-stuff": {"@attr1": "string value", "child": True}}
xml_str = xmltodict.unparse({"action": action1}, full_document=False)

# 解析为lxml树
tree = etree.fromstring(xml_str)

# 后续可使用lxml API操作该树,比如添加到其他节点中

如果不想经过XML字符串中转,也可以自己实现递归转换函数(灵活适配xmltodict的字典格式):

from lxml import etree

def dict_to_lxml(node_dict, parent=None):
    if parent is None:
        root_tag = next(iter(node_dict.keys()))
        root = etree.Element(root_tag)
        _dict_to_lxml(node_dict[root_tag], root)
        return root
    else:
        _dict_to_lxml(node_dict, parent)

def _dict_to_lxml(data, parent):
    if isinstance(data, dict):
        for key, value in data.items():
            if key.startswith("@"):
                # 处理属性
                parent.set(key[1:], str(value))
            elif key == "#text":
                # 处理文本内容
                parent.text = str(value)
            else:
                # 处理子节点
                if isinstance(value, list):
                    # 列表生成多个同标签节点
                    for item in value:
                        child = etree.SubElement(parent, key)
                        _dict_to_lxml(item, child)
                else:
                    child = etree.SubElement(parent, key)
                    _dict_to_lxml(value, child)
    else:
        # 纯文本节点
        parent.text = str(data)

# 使用示例
action1 = {"@id": 1, "some-nested-stuff": {"@attr1": "string value", "child": True}}
root_dict = {"root": [{"action": action1}, {"action-group": {"@groupId":1, "action": [{"@id":2}, {"@id":3}]}}, {"action": {"@id":4}}]}
tree = dict_to_lxml(root_dict)
print(etree.tostring(tree, pretty_print=True, encoding="utf-8").decode())

这个函数可以直接把xmltodict格式的字典转换成lxml树,支持属性、嵌套节点和列表类型的多节点。


内容的提问来源于stack exchange,提问作者Arpad Horvath -- Слава</think_never_used_51bce0c785ca2f68081bfa7d91973934>

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:01:13