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" )
四、结构保留关键说明
- 读取时的XPath设置:若原XML为
<root>包裹多个<Part>节点的结构,xpath=".//Part"会直接提取所有零件节点数据,避免解析层级错误。 - 导出时的节点配置:
root_name="root"和row_name="Part"确保输出XML的外层根节点和每行数据的包裹节点与原文件完全一致。 - 过滤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
相关产品推荐
相关产品推荐

