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

求助:将API返回的XML数据转换为Pandas DataFrame

把XML转换为Pandas DataFrame的完整解决方案

问题背景

给定以下XML格式的API响应:

<?xml version="1.0" encoding="UTF-8"?>
<sunSpecPlantExtract t="2022-08-09T16:54:53Z"><plant id="bb2c469c-9b63-4e64-b95c-6806578889ae" v="1" locale="en-US"><name>Palmyra LLC / Unique Smile</name><activationDate>2016-07-11</activationDate><location><latitude/><longitude/><line1>21 Main St.</line1><city>Milford</city><state>MA</state><postal>01757</postal><timezone>-4:00</timezone></location></plant><sunspecData v="1" periodStart="2022-08-08T06:00:00Z" periodEnd="2022-08-08T23:59:00Z"><d lid="00:90:C2:F7:8C:9C" man="solren" mod="2_20151205" t="2022-08-08T23:40:56Z"><m id="201" sn="F78C9C"><p id="WH">127100</p><p id="WHL">157155200</p><p id="W">9357.4</p></m></d></sunspecData></sunSpecPlantExtract>

使用以下代码转换时,无法提取完整数据:

root = ET.XML(response_data) # element tree
all_records = []
for i, child in enumerate(root):
    record = {}
    for subchild in child:
        record[subchild.tag] = subchild.text
    all_records.append(record)
return pd.DataFrame(all_records)

得到的不完整结果:

name    activationDate  location    d
0   Jack Efird #35  2019-07-03  NaN NaN
1   NaN NaN NaN NaN

问题分析

原代码存在以下局限:

  • 仅遍历根节点的直接子元素(plant和sunspecData),将关联数据拆分为两条独立记录,不符合业务逻辑
  • 未提取元素的属性信息(如plant的id、sunspecData的periodStart等)
  • 未处理嵌套结构(如location下的子字段、d/m/p层级的数据)
  • 忽略了空元素和非叶子节点的内容提取

完整解决方案

使用递归方式提取XML中的所有属性和嵌套子元素,将关联数据合并为单条记录后转换为DataFrame:

import xml.etree.ElementTree as ET
import pandas as pd

def extract_element_data(element, parent_key=''):
    data = {}
    # 提取当前元素的所有属性
    for attr, value in element.attrib.items():
        key = f"{parent_key}_{attr}" if parent_key else attr
        data[key] = value
    # 递归处理子元素
    for child in element:
        child_key = f"{parent_key}_{child.tag}" if parent_key else child.tag
        # 处理叶子节点(无嵌套子元素且有有效文本)
        if len(child) == 0:
            if child.text and child.text.strip():
                data[child_key] = child.text.strip()
        else:
            # 处理嵌套节点,递归提取后合并数据
            child_data = extract_element_data(child, child_key)
            data.update(child_data)
    return data

# 解析XML数据(替换为你的response_data变量)
response_data = """<?xml version="1.0" encoding="UTF-8"?>
<sunSpecPlantExtract t="2022-08-09T16:54:53Z"><plant id="bb2c469c-9b63-4e64-b95c-6806578889ae" v="1" locale="en-US"><name>Palmyra LLC / Unique Smile</name><activationDate>2016-07-11</activationDate><location><latitude/><longitude/><line1>21 Main St.</line1><city>Milford</city><state>MA</state><postal>01757</postal><timezone>-4:00</timezone></location></plant><sunspecData v="1" periodStart="2022-08-08T06:00:00Z" periodEnd="2022-08-08T23:59:00Z"><d lid="00:90:C2:F7:8C:9C" man="solren" mod="2_20151205" t="2022-08-08T23:40:56Z"><m id="201" sn="F78C9C"><p id="WH">127100</p><p id="WHL">157155200</p><p id="W">9357.4</p></m></d></sunspecData></sunSpecPlantExtract>
"""

root = ET.fromstring(response_data)

# 合并所有节点的数据为单条记录
full_record = {}
for child_node in root:
    node_data = extract_element_data(child_node)
    full_record.update(node_data)

# 转换为DataFrame
df = pd.DataFrame([full_record])
print(df)

输出结果

运行后将得到包含所有字段的完整DataFrame:

sunSpecPlantExtract_t                     plant_id plant_v plant_locale                    name activationDate location_latitude location_longitude location_line1 location_city location_state location_postal location_timezone sunspecData_v    sunspecData_periodStart      sunspecData_periodEnd            d_lid d_man     d_mod               d_t m_id   m_sn p_WH    p_WHL    p_W
0  2022-08-09T16:54:53Z  bb2c469c-9b63-4e64-b95c-...       1        en-US  Palmyra LLC / Unique Smile      2016-07-11                                 21 Main St.        Milford             MA          01757           -4:00             1  2022-08-08T06:00:00Z  2022-08-08T23:59:00Z  00:90:C2:F7:8C:9C  solren  2_20151205  2022-08-08T23:40:56Z    201  F78C9C  127100  157155200  9357.4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:27:28