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

Python实现多XML文件导入单个Excel分工作表的问题排查

问题描述

初始单文件处理问题

需要将20个结构相同、仅数值不同的XML文件导入到一个Excel文件,每个XML对应独立工作表,仅提取X和Y值。最初处理单个XML的代码如下:

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

file_path = file_path
root = ET.parse(file_path).getroot()
for Point in root.findall('Point'):
    X = float(Point.find('X').text)
    Y = float(Point.find('Y').text)
    kraft_all = [Y]
    data = {'Weg/mm': [X], 'Kraft/N': [Y],'Max. Kraft/N':max(kraft_all)}
    df = pd.DataFrame.from_dict(data)
    print(df)

遇到两个问题:

  • 为何每个值都对应列名?如何仅在首行显示列名?
  • 如何获取Y值的最大值并写入第三列“Max. Kraft/N”的首个单元格?

此前已通过pd.read_csv和df.to_excel实现多CSV导入Excel,解决上述问题后计划自行处理多文件,也希望得到相关建议。


更新:多文件处理报错(2023.10.09)

单个XML处理代码已修正可行:

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

file_path = r'C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\tru Beige\tru beige-1.xml'
root = ET.parse(file_path).getroot()
as_list = []
for Point in root.findall("Point"):
    X = float(Point.find("X").text)
    Y = float(Point.find("Y").text)
    line = {"Weg/mm": X, "Kraft/N": Y}
    as_list.append(line)
df = pd.DataFrame.from_dict(as_list)
print(df)
excel_path = r'C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\beige.xlsx'
writer = pd.ExcelWriter(excel_path,engine='openpyxl')
df.to_excel(excel_writer=writer,sheet_name='tru beige-1')
writer.close()

现在需要实现:

  1. 从文件夹导入多个XML生成多个DataFrame
  2. 将这些DataFrame导入到一个Excel的多个工作表中

编写的代码报错:ValueError: names does not match length of child elements in xpath

import glob
import pandas as pd
import os
from pathlib import Path

def load_xml(files):
    column = ["Weg[mm]","Kraft[N]"]
    df1 = pd.concat([pd.read_xml(file, names=column) for file in files])
    return df1

excel_path = r'C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\beige.xlsx'
writer = pd.ExcelWriter(excel_path,engine='openpyxl')
num=1
for root,dirs,files in os.walk(r"C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\tru Beige"):
    print(root)
    print(dirs)
    print(files)
    for file in files:
        xml_files = Path(r"C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\tru Beige").glob('*.xml') 
        df = load_xml(xml_files)
        df.to_excel(excel_writer=writer,sheet_name=file)
    writer.close()

请检查并修正代码错误。


解决方案

一、初始单文件问题的修正

问题1:每个值对应列名的原因及解决

原代码在循环中每次创建新的DataFrame,导致每一行都生成带列名的小表格。正确做法是先收集所有数据到列表,再一次性生成完整DataFrame:

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

file_path = "你的文件路径.xml"
root = ET.parse(file_path).getroot()
data_list = []
kraft_all = []

for Point in root.findall('Point'):
    X = float(Point.find('X').text)
    Y = float(Point.find('Y').text)
    data_list.append({'Weg/mm': X, 'Kraft/N': Y})
    kraft_all.append(Y)

# 生成完整DataFrame
df = pd.DataFrame(data_list)
# 添加最大值列,仅首单元格填充
df['Max. Kraft/N'] = None
df.loc[0, 'Max. Kraft/N'] = max(kraft_all)

print(df)

问题2:Y值最大值写入第三列首单元格

上述代码中,先收集所有Y值到kraft_all列表,计算最大值后通过df.loc[0, 'Max. Kraft/N']将值写入首行对应列,其余行设为None,符合需求。

二、多文件处理代码的错误修正

原代码存在pd.read_xml配置错误、重复处理文件、工作表名称不规范等问题,修正后的代码如下:

import pandas as pd
from pathlib import Path
import xml.etree.ElementTree as ET

# 单个XML文件处理函数,复用已验证的解析逻辑
def process_single_xml(file_path):
    root = ET.parse(file_path).getroot()
    as_list = []
    kraft_all = []
    for Point in root.findall("Point"):
        X = float(Point.find("X").text)
        Y = float(Point.find("Y").text)
        as_list.append({"Weg/mm": X, "Kraft/N": Y})
        kraft_all.append(Y)
    df = pd.DataFrame(as_list)
    # 添加最大值列
    df['Max. Kraft/N'] = None
    if kraft_all:
        df.loc[0, 'Max. Kraft/N'] = max(kraft_all)
    return df

# 配置路径
xml_dir = r"C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\tru Beige"
excel_path = r"C:\Users\xli\OneDrive - TFI Aachen GmbH\Excel_Beige und Weiß_Tru\beige.xlsx"

# 批量处理并写入Excel
with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
    # 遍历文件夹下所有XML文件
    for xml_file in Path(xml_dir).glob('*.xml'):
        # 用不带后缀的文件名作为工作表名称,避免Excel报错
        sheet_name = xml_file.stem
        # 处理单个XML文件
        df = process_single_xml(xml_file)
        # 写入工作表,不保留索引
        df.to_excel(writer, sheet_name=sheet_name, index=False)

关键修正点:

  1. 放弃pd.read_xml,改用已验证的xml.etree.ElementTree解析逻辑,避免xpath配置错误
  2. 直接用Path.glob遍历XML文件,避免os.walk嵌套循环导致的重复处理
  3. 用xml_file.stem获取不带后缀的文件名作为工作表名称,规避Excel不允许的字符
  4. 在单个文件处理函数中集成最大值列逻辑,保证每个工作表的数据完整性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:58:14