如何处理多分支XML并将重复标签数据完整保存至DataFrame?
问题描述
XML文件同一分支下存在大量重复标签(如<RowData>),使用原有代码时这类重复标签的数据会被后续数据覆盖,无法完整留存,需要实现将所有数据完整存储到DataFrame中。
原有尝试代码:
import pandas as pd from xml.etree import ElementTree path=str('data.xml') with open(path, mode="r", encoding="utf-8") as f: xml_file = f.read() items_delete=['<ObjectRelation>','</ObjectRelation>','<List>','</List>','<RowData>','</RowData>','<Kind>','</Kind>'] for item in items_delete: xml_file=xml_file.replace(item, '') df = pd.read_xml(xml_file)
XML数据示例:
<ItemList> <ItemData> <ObjectRelation> <ObjectCadastreNr>01000180062</ObjectCadastreNr> <ObjectType>PARCEL</ObjectType> </ObjectRelation> <List> <RowData> <Kind> <KindId>7312050201</KindId> <KindName>ekspluatācijas aizsargjoslas teritorija gar elektrisko tīklu kabeļu līniju</KindName> </Kind> <Nr>1</Nr> <EstablishDate>1997-02-24</EstablishDate> <Area>0.0127</Area> <Measure>ha</Measure> </RowData> <RowData> <Kind> <KindId>7312040200</KindId> <KindName>ekspluatācijas aizsargjoslas teritorija gar elektronisko sakaru tīklu gaisvadu līniju</KindName> </Kind> <Nr>3</Nr> <EstablishDate>1996-01-13</EstablishDate> </RowData> </List> </ItemData> <ItemData> <ObjectRelation> <ObjectCadastreNr>01000180062</ObjectCadastreNr> <ObjectType>PARCEL</ObjectType> </ObjectRelation> <List> <RowData> <Kind> <KindId>7312060100</KindId> <KindName>ekspluatācijas aizsargjoslas teritorija gar pazemes siltumvadu, siltumapgādes iekārtu un būvi</KindName> </Kind> <Nr>5</Nr> <EstablishDate>1997-01-13</EstablishDate> </RowData> </List> </ItemData> </ItemList>
解决方案
原有代码的问题在于直接删除了所有嵌套标签的外层结构,导致XML层级混乱,pandas无法识别重复的<RowData>节点,最终出现数据覆盖。正确的做法是手动解析XML结构,将每个<ItemData>下的公共信息(ObjectRelation里的字段)与每个<RowData>的信息合并,再统一存入DataFrame。
实现代码如下:
import pandas as pd from xml.etree import ElementTree as ET # 解析XML文件 tree = ET.parse('data.xml') root = tree.getroot() # 存储所有行数据的列表 all_rows = [] # 遍历每个ItemData节点 for item_data in root.findall('ItemData'): # 获取ObjectRelation下的公共字段 obj_relation = item_data.find('ObjectRelation') cadastre_nr = obj_relation.find('ObjectCadastreNr').text obj_type = obj_relation.find('ObjectType').text # 遍历当前ItemData下的所有RowData节点 for row_data in item_data.find('List').findall('RowData'): # 初始化当前行的字典,先存入公共字段 row_dict = { 'ObjectCadastreNr': cadastre_nr, 'ObjectType': obj_type } # 获取Kind下的字段 kind = row_data.find('Kind') row_dict['KindId'] = kind.find('KindId').text row_dict['KindName'] = kind.find('KindName').text # 获取RowData下的其他字段 for elem in row_data: if elem.tag != 'Kind': # 跳过已经处理的Kind节点 row_dict[elem.tag] = elem.text if elem.text is not None else None # 将当前行添加到列表 all_rows.append(row_dict) # 转换为DataFrame df = pd.DataFrame(all_rows) print(df)
代码说明
- 手动遍历XML的层级结构,确保每个
<RowData>都被单独处理,不会被覆盖 - 将
<ObjectRelation>中的公共信息(如地籍号、对象类型)复制到每个对应的<RowData>行中,保证数据的关联性 - 处理可能存在的空值(如部分RowData没有
Area和Measure字段),避免报错 - 最终生成的DataFrame会包含所有RowData的完整数据,每个RowData对应一行
内容的提问来源于Stack Exchange,提问作者Tetiana Lem
相关产品推荐
相关产品推荐

