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

基于SOURCE属性提取SOURCEFIELD子元素并生成字典的实现方法

解析XML生成SOURCE与SOURCEFIELD属性对应字典

需求描述

解析包含多个<SOURCE>元素的XML文件,每个<SOURCE>节点下包含多个带自有属性的<SOURCEFIELD>子元素,最终生成格式为{SOURCE_NAME: [SOURCEFIELD属性字典列表]}的字典结构,其中SOURCE_NAME为<SOURCE>元素的NAME属性值。

XML示例

<SOURCE BUSINESSNAME ="" DATABASETYPE ="Netezza" DBDNAME ="SHEDW_CORE" DESCRIPTION ="" NAME ="DIM_NRC_CUSTOMER_TMP" OBJECTVERSION ="1" OWNERNAME ="ADMIN" VERSIONNUMBER ="1">
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="numeric" DESCRIPTION ="" FIELDNUMBER ="1" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="14" LEVEL ="0" NAME ="DIM_CUSTOMER_SQN" NULLABLE ="NULL" OCCURS ="0" OFFSET ="0" PHYSICALLENGTH ="12" PHYSICALOFFSET ="0" PICTURETEXT ="" PRECISION ="12" SCALE ="0" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="timestamp" DESCRIPTION ="" FIELDNUMBER ="2" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="19" LEVEL ="0" NAME ="LOAD_END_DATE" NULLABLE ="NULL" OCCURS ="0" OFFSET ="14" PHYSICALLENGTH ="26" PHYSICALOFFSET ="12" PICTURETEXT ="" PRECISION ="26" SCALE ="6" USAGE_FLAGS =""/>
    </SOURCE>
    <SOURCE BUSINESSNAME ="" DATABASETYPE ="Netezza" DBDNAME ="SHEDW_CORE" DESCRIPTION ="" NAME ="SAT_CONTACT" OBJECTVERSION ="1" OWNERNAME ="ADMIN" VERSIONNUMBER ="1">
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="numeric" DESCRIPTION ="" FIELDNUMBER ="1" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="PRIMARY KEY" LENGTH ="14" LEVEL ="0" NAME ="SAT_CONTACT_SQN" NULLABLE ="NOTNULL" OCCURS ="0" OFFSET ="0" PHYSICALLENGTH ="12" PHYSICALOFFSET ="0" PICTURETEXT ="" PRECISION ="12" SCALE ="0" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="numeric" DESCRIPTION ="" FIELDNUMBER ="2" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="14" LEVEL ="0" NAME ="CONTACT_SQN" NULLABLE ="NOTNULL" OCCURS ="0" OFFSET ="14" PHYSICALLENGTH ="12" PHYSICALOFFSET ="12" PICTURETEXT ="" PRECISION ="12" SCALE ="0" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="timestamp" DESCRIPTION ="" FIELDNUMBER ="3" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="19" LEVEL ="0" NAME ="LOAD_DATE" NULLABLE ="NOTNULL" OCCURS ="0" OFFSET ="28" PHYSICALLENGTH ="26" PHYSICALOFFSET ="24" PICTURETEXT ="" PRECISION ="26" SCALE ="6" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="timestamp" DESCRIPTION ="" FIELDNUMBER ="4" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="19" LEVEL ="0" NAME ="LOAD_END_DATE" NULLABLE ="NULL" OCCURS ="0" OFFSET ="47" PHYSICALLENGTH ="26" PHYSICALOFFSET ="50" PICTURETEXT ="" PRECISION ="26" SCALE ="6" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="varchar" DESCRIPTION ="" FIELDNUMBER ="5" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="0" LEVEL ="0" NAME ="REC_SOURCE" NULLABLE ="NULL" OCCURS ="0" OFFSET ="66" PHYSICALLENGTH ="30" PHYSICALOFFSET ="76" PICTURETEXT ="" PRECISION ="30" SCALE ="0" USAGE_FLAGS =""/>
        </SOURCE>

现有问题代码

import xml.etree.ElementTree as ET

if not ET.parse('C:\\Desktop\\xml\\m_DM_DIM_NRC_CUSTOMER.xml'):
    raise SyntaxError
else:
   print("The XML is valid")
   tree = ET.parse('C:\\Desktop\\xml\\m_DM_DIM_NRC_CUSTOMER.xml')
   root = tree.getroot()][1]][1]  # 语法错误

dd = []
for source in root.iter('SOURCE'):
    print("\n")
    sourcename = source.attrib['NAME']

    print("*********** The DETAILS of  SOURCE: %s: : ***********" %sourcename)
    print(source.attrib)
    print("*********** The COLUMN NAMES of  SOURCE: %s ***********" % sourcename)
    for sourcefields in source.iter("SOURCEFIELD"):
        print(sourcefields.attrib)
        dd.append(sourcefields.attrib)
        dict[sourcename] = dd  # 复用全局列表+误用内置类型名

问题分析

  1. 语法错误:root = tree.getroot()][1]][1存在多余的括号和索引,应直接写root = tree.getroot()
  2. 全局列表复用:dd是全局列表,每次遍历<SOURCE>时未重置,导致所有<SOURCEFIELD>属性都被累积到同一个列表,最终所有SOURCE_NAME对应相同的字段集合
  3. 误用内置类型名:dict是Python内置字典类型,不能用作自定义变量名,需替换为自定义变量(如result)

正确实现代码

import xml.etree.ElementTree as ET

# 解析XML文件
try:
    tree = ET.parse('C:\\Desktop\\xml\\m_DM_DIM_NRC_CUSTOMER.xml')
    print("The XML is valid")
except ET.ParseError:
    raise SyntaxError("Invalid XML file")

root = tree.getroot()
result = {}  # 初始化结果字典

for source in root.iter('SOURCE'):
    sourcename = source.attrib['NAME']
    # 为当前SOURCE创建单独的字段列表,避免跨SOURCE污染
    field_list = []
    for sourcefield in source.iter("SOURCEFIELD"):
        # 将SOURCEFIELD的属性字典加入列表
        field_list.append(sourcefield.attrib)
    # 将当前SOURCE的字段列表映射到结果字典
    result[sourcename] = field_list

# 打印或使用结果
import pprint
pprint.pprint(result)

预期输出格式

{
    "DIM_NRC_CUSTOMER_TMP": [
        {"BUSINESSNAME": "", "DATATYPE": "numeric", ...},
        {"BUSINESSNAME": "", "DATATYPE": "timestamp", ...}
    ],
    "SAT_CONTACT": [
        {"BUSINESSNAME": "", "DATATYPE": "numeric", ...},
        {"BUSINESSNAME": "", "DATATYPE": "numeric", ...},
        ...
    ]
}

内容的提问来源于stack exchange,提问作者Debashish Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:37:11