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

如何用Python生成器将XML数据转为结构合理的字典?

XML转字典优化:避免索引访问子容器内容

我有一段XML数据,希望用生成器将其整理为字典,且仅保留指定子容器。原代码如下:

import xml.etree.ElementTree as Etree

xml_file = '\
<Container>\
    <Main Type="main1" var1="var1"/>\
    <SubContainer1>\
        <Sub Type="sub1" var1="var1" var2="var2"/>\
        <Sub Type="sub2" var1="var1" var2="var2"/>\
    </SubContainer1>\
    <SubContainer2>\
        <Var ObjectId="0000000001" Name="Name1" Value="1" />\
        <Var ObjectId="0000000001" Name="Name2" Value="2" />\
        <Var ObjectId="0000000001" Name="Name3" Value="3" />\
        <Var ObjectId="0000000001" Name="Name4" Value="4" />\
        <Var ObjectId="0000000001" Name="Name5" Value="5" />\
        <Var ObjectId="0000000001" Name="Name6" Value="6" />\
    </SubContainer2>\
</Container>'

xml_tree = Etree.fromstring(xml_file)
xml_dict = {}

sub_containers = ['SubContainer1','SubContainer2']
for c in sub_containers:
    xml_dict[c] = [{x.tag : x.attrib} for x in xml_tree.findall(f'.//{c}/*')]

print(xml_dict)

原代码生成的字典结构中,每个子容器对应一个列表,访问元素必须通过xml_dict['SubContainer1'][0]这样的索引,操作繁琐。以下是两种优化方案:


方案1:按子元素标签分组

将同一子容器下的同标签元素整合到对应键的列表中,结构更清晰,无需通过外层索引访问标签组:

import xml.etree.ElementTree as Etree

xml_file = '\
<Container>\
    <Main Type="main1" var1="var1"/>\
    <SubContainer1>\
        <Sub Type="sub1" var1="var1" var2="var2"/>\
        <Sub Type="sub2" var1="var1" var2="var2"/>\
    </SubContainer1>\
    <SubContainer2>\
        <Var ObjectId="0000000001" Name="Name1" Value="1" />\
        <Var ObjectId="0000000001" Name="Name2" Value="2" />\
        <Var ObjectId="0000000001" Name="Name3" Value="3" />\
        <Var ObjectId="0000000001" Name="Name4" Value="4" />\
        <Var ObjectId="0000000001" Name="Name5" Value="5" />\
        <Var ObjectId="0000000001" Name="Name6" Value="6" />\
    </SubContainer2>\
</Container>'

xml_tree = Etree.fromstring(xml_file)
xml_dict = {}

sub_containers = ['SubContainer1','SubContainer2']
for c in sub_containers:
    container_data = {}
    for elem in xml_tree.findall(f'.//{c}/*'):
        if elem.tag not in container_data:
            container_data[elem.tag] = []
        container_data[elem.tag].append(elem.attrib)
    xml_dict[c] = container_data

print(xml_dict)

输出结构:

{
    'SubContainer1': {
        'Sub': [
            {'Type': 'sub1', 'var1': 'var1', 'var2': 'var2'},
            {'Type': 'sub2', 'var1': 'var1', 'var2': 'var2'}
        ]
    },
    'SubContainer2': {
        'Var': [
            {'ObjectId': '0000000001', 'Name': 'Name1', 'Value': '1'},
            {'ObjectId': '0000000001', 'Name': 'Name2', 'Value': '2'},
            {'ObjectId': '0000000001', 'Name': 'Name3', 'Value': '3'},
            {'ObjectId': '0000000001', 'Name': 'Name4', 'Value': '4'},
            {'ObjectId': '0000000001', 'Name': 'Name5', 'Value': '5'},
            {'ObjectId': '0000000001', 'Name': 'Name6', 'Value': '6'}
        ]
    }
}

访问方式:直接通过标签键获取所有同类型元素,比如xml_dict['SubContainer1']['Sub'];若需单个元素,再用索引定位(如xml_dict['SubContainer1']['Sub'][0])。


方案2:用元素唯一属性作为键

如果子元素存在唯一标识属性(如Sub的Type、Var的Name),可直接将该属性值作为键,实现无索引直接访问目标元素:

import xml.etree.ElementTree as Etree

xml_file = '\
<Container>\
    <Main Type="main1" var1="var1"/>\
    <SubContainer1>\
        <Sub Type="sub1" var1="var1" var2="var2"/>\
        <Sub Type="sub2" var1="var1" var2="var2"/>\
    </SubContainer1>\
    <SubContainer2>\
        <Var ObjectId="0000000001" Name="Name1" Value="1" />\
        <Var ObjectId="0000000001" Name="Name2" Value="2" />\
        <Var ObjectId="0000000001" Name="Name3" Value="3" />\
        <Var ObjectId="0000000001" Name="Name4" Value="4" />\
        <Var ObjectId="0000000001" Name="Name5" Value="5" />\
        <Var ObjectId="0000000001" Name="Name6" Value="6" />\
    </SubContainer2>\
</Container>'

xml_tree = Etree.fromstring(xml_file)
xml_dict = {}

# 定义每个子容器对应的唯一属性键
container_key_map = {
    'SubContainer1': 'Type',
    'SubContainer2': 'Name'
}

for c, key_attr in container_key_map.items():
    container_data = {}
    for elem in xml_tree.findall(f'.//{c}/*'):
        container_data[elem.attrib[key_attr]] = elem.attrib
    xml_dict[c] = container_data

print(xml_dict)

输出结构:

{
    'SubContainer1': {
        'sub1': {'Type': 'sub1', 'var1': 'var1', 'var2': 'var2'},
        'sub2': {'Type': 'sub2', 'var1': 'var1', 'var2': 'var2'}
    },
    'SubContainer2': {
        'Name1': {'ObjectId': '0000000001', 'Name': 'Name1', 'Value': '1'},
        'Name2': {'ObjectId': '0000000001', 'Name': 'Name2', 'Value': '2'},
        'Name3': {'ObjectId': '0000000001', 'Name': 'Name3', 'Value': '3'},
        'Name4': {'ObjectId': '0000000001', 'Name': 'Name4', 'Value': '4'},
        'Name5': {'ObjectId': '0000000001', 'Name': 'Name5', 'Value': '5'},
        'Name6': {'ObjectId': '0000000001', 'Name': 'Name6', 'Value': '6'}
    }
}

访问方式:直接通过属性值访问目标元素,比如xml_dict['SubContainer2']['Name3']即可获取对应Var元素的属性字典,完全无需索引。


内容的提问来源于stack exchange,提问作者rbx 775

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:47:07