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

Python合并多XML文件去重报错排查及代码逻辑解析

合并XML文件并去重Part ID:报错修复与代码解析

一、报错原因

pd.concat()本身不会触发FileNotFoundError,实际错误来自前置的pd.read_xml(file)调用。核心问题是:os.listdir(input_folder)仅返回文件夹内的文件名(如file1.xml),而非完整文件路径。当Python脚本的工作目录与input_folder不在同一层级时,pd.read_xml会在当前工作目录查找文件,自然找不到目标文件,从而抛出错误。

二、原错误代码逐行拆解

假设你使用的代码如下:

import pandas as pd
import os

input_folder = "./xml_files"
output_file = "merged.xml"

xml_files = os.listdir(input_folder)
dfs = []
for file in xml_files:
    df = pd.read_xml(file)  # ❌ 错误:使用纯文件名而非完整路径
    dfs.append(df)

merged_df = pd.concat(dfs)
merged_df.drop_duplicates(subset="Part ID", keep="first", inplace=True)
merged_df.to_xml(output_file, index=False)

逐行逻辑解析:

  • import pandas as pd/import os:导入处理XML的pandas库和文件操作的os库
  • input_folder = "./xml_files":指定待合并XML文件的存放路径(相对路径)
  • output_file = "merged.xml":指定合并去重后的输出文件名
  • xml_files = os.listdir(input_folder):读取目标文件夹下的所有文件名称,返回仅包含文件名的列表
  • for file in xml_files::遍历每个文件名
    • df = pd.read_xml(file):尝试读取文件,但未拼接完整路径,若脚本工作目录与目标文件夹不一致则会找不到文件
  • merged_df = pd.concat(dfs):将所有读取到的DataFrame纵向合并
  • merged_df.drop_duplicates(...):根据Part ID字段去重,保留首次出现的条目
  • merged_df.to_xml(...):将去重后的DataFrame导出为XML文件

三、修复后代码(保留原XML结构)

要保证输出XML与原文件结构一致,需在读取和导出时匹配原XML的节点层级。以下是修复后的完整代码:

import pandas as pd
import os

input_folder = "./xml_files"
output_file = "merged.xml"

dfs = []
# 仅处理文件夹内的XML文件
for filename in os.listdir(input_folder):
    if filename.endswith(".xml"):
        # 拼接完整文件路径,避免路径错误
        file_path = os.path.join(input_folder, filename)
        # 指定XPath提取<Part>节点,匹配原XML结构
        df = pd.read_xml(file_path, xpath=".//Part")
        dfs.append(df)

# 合并所有DataFrame,重置索引避免冲突
merged_df = pd.concat(dfs, ignore_index=True)
# 根据Part ID去重,保留第一个出现的条目
merged_df.drop_duplicates(subset="Part ID", keep="first", inplace=True)

# 导出XML,指定根节点和行节点,与原结构对齐
merged_df.to_xml(
    output_file,
    index=False,
    root_name="root",
    row_name="Part",
    encoding="utf-8"
)

四、结构保留关键说明

  1. 读取时的XPath设置:若原XML为<root>包裹多个<Part>节点的结构,xpath=".//Part"会直接提取所有零件节点数据,避免解析层级错误。
  2. 导出时的节点配置:root_name="root"和row_name="Part"确保输出XML的外层根节点和每行数据的包裹节点与原文件完全一致。
  3. 过滤XML文件:filename.endswith(".xml")避免读取文件夹内的非XML文件,防止无效解析报错。

五、验证示例

原XML文件示例

file1.xml

<root>
  <Part>
    <Part ID>P001</Part ID>
    <Name>Screw</Name>
    <Price>0.5</Price>
  </Part>
</root>

file2.xml

<root>
  <Part>
    <Part ID>P001</Part ID>
    <Name>Screw</Name>
    <Price>0.5</Price>
  </Part>
  <Part>
    <Part ID>P002</Part ID>
    <Name>Nut</Name>
    <Price>0.3</Price>
  </Part>
</root>

合并去重后输出XML

<root>
  <Part>
    <Part ID>P001</Part ID>
    <Name>Screw</Name>
    <Price>0.5</Price>
  </Part>
  <Part>
    <Part ID>P002</Part ID>
    <Name>Nut</Name>
    <Price>0.3</Price>
  </Part>
</root>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:07:07