是否有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>
相关产品推荐
相关产品推荐

