Python XML/Pandas:如何合并嵌套XML中的关联数据?
解决嵌套XML中RSku与对应Blade信息关联提取的问题
问题分析
直接用pd.read_xml分别提取RSku和Blade数据的方式,在多RSku多Blade场景下会出现数据行数不匹配,且无法建立RSku与Blade的关联关系。核心原因是这种方式忽略了XML的层级结构,没有将每个Blade与其所属的RSku绑定。
解决方案
通过遍历XML的层级结构,逐个处理每个RSku节点,同时提取其下所有Blade节点的信息,将RSku属性与对应的Blade属性合并后存入列表,最终转换为DataFrame。这种方式能保证每一行数据都对应一个RSku-Blade的关联对。
实现代码
import xml.etree.ElementTree as ET import pandas as pd # 示例XML数据 xml1 = ('''<?xml version="1.0" encoding="utf-8"?> <TopologyDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <RSkus> <RSku ID="V1" Deprecated="true" Owner="Unknown" Generation="1"> <Devices> <Device ID="1" SkuID="Switch" Role="xD" /> </Devices> <Blades> <Blade ID="{1-20}" SkuID="SBlade" /> </Blades> <Interfaces> <Interface ID="COM" HardwareID="NS1" SlotID="COM1" Type="serial" /> <Interface ID="LINK" HardwareID="TS1" SlotID="UPLINK_1" Type="serial" /> </Interfaces> <Wires> <WireGroup Type="network"> <Wire LocationA="NS1" SlotA="{1-20}" LocationB="{1-20}" SlotB="NIC1" /> </WireGroup> <WireGroup Type="serial"> <Wire LocationA="TS1" SlotA="{7001-7020}" LocationB="{1-20}" SlotB="COM1" /> </WireGroup> </Wires> </RSku> <!-- 多Blade的RSku示例 --> <RSku ID="V2" Deprecated="false" Owner="TeamA" Generation="2"> <Blades> <Blade ID="B1" SkuID="XBlade" /> <Blade ID="B2" SkuID="YBlade" /> </Blades> </RSku> </RSkus> </TopologyDefinition> ''') # 解析XML root = ET.fromstring(xml1) # 存储合并后的数据 combined_data = [] # 遍历每个RSku节点 for rsku in root.findall('.//RSku'): # 获取当前RSku的所有属性 rsku_info = rsku.attrib # 获取当前RSku下的所有Blade节点 blades = rsku.findall('.//Blade') # 为每个Blade生成一行关联数据 for blade in blades: blade_info = blade.attrib # 合并RSku和Blade属性 row = {**rsku_info, **blade_info} combined_data.append(row) # 转换为DataFrame result_df = pd.DataFrame(combined_data) print(result_df)
代码说明
- XML解析:使用Python内置的
xml.etree.ElementTree模块解析XML字符串,无需额外安装依赖。 - 层级遍历:通过
findall('.//RSku')定位所有RSku节点,再对每个RSku节点查找其下的Blade节点,确保Blade与所属RSku关联。 - 属性合并:将RSku的属性字典与Blade的属性字典合并,形成包含两类信息的单行数据。
- DataFrame转换:将所有合并后的字典存入列表,转换为DataFrame,得到每行对应一个RSku-Blade关联对的结果。
输出结果示例
ID Deprecated Owner Generation ID SkuID 0 V1 true Unknown 1 {1-20} SBlade 1 V2 false TeamA 2 B1 XBlade 2 V2 false TeamA 2 B2 YBlade
内容的提问来源于stack exchange,提问作者John Stud
相关产品推荐
相关产品推荐

