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

Python实现XML匹配Excel数据替换标签报错求助

问题

我有多个命名格式为LLL_XXXXXXXXX_title.xml的XML文件(LLL_后固定为8位字符),另有一个含900+行的Excel文件,结构如下:

referencedtp1dtp2dtp3
ABC0D0121_blabla1_1_blablabla1_1_1_blablablabla
ABC0D0131_blabla1_1_blablabla1_1_1_blablablabla
ABC0D0141_blabla1_1_blablabla1_1_1_blablablabla
ABT0G0121_blabla1_1_blablabla1_1_1_blablablabla

XML文件中包含<dtp1>text</dtp1>、<dtp2>text</dtp2>、<dtp3>text</dtp3>标签,我希望通过Python脚本实现:遍历XML文件,提取文件名中LLL_后的8位字符,匹配Excel的reference列,获取对应dtp1、dtp2、dtp3列的值,替换XML标签文本。

我作为Python初学者编写了如下脚本:

import numpy as np
import openpyxl
import pandas as pd
import xml.etree.ElementTree as ET
import os

table1 = pd.read_excel('C:/Users/Documents/datatypes.xlsx', na_values=['NA'])
table2 = table1.replace('\xa0', ' ',regex=True)

for root, dirs, files in os.walk("."):
    for file in files :
        if file[-4:] == '.xml':
            #print(file)
            xml = ET.parse('LLL_ABC0D012_title.xml')
            root = xml.getroot()
            dtp1_xml = root[8]
            dtp2_xml = root[9]          
            dtp3_xml = root[10]
            num = file[4:12]
            #print(num)
            dtp1_excel = table2['dtp1'].where(table2['reference'] == num)
            dtp1_xml.text = dtp1_excel
            #print(dtp1_xml.text)
            ET.indent(root)
            xml.write("LLL_ABC0D012_title.xml", encoding='utf-8', xml_declaration=True, method='xml')

但脚本运行异常,dtp1_excel未返回匹配的单元格值,而是输出全NaN的Series:

0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
      ...
931    NaN
932    NaN
933    NaN
934    NaN
935    NaN
Name: dtp1, Length: 936, dtype: object

我的Excel中reference和dtp1列无NaN值,应该只返回单个单元格值。请问我的实现思路哪里出错了?


问题分析与修复方案

核心错误点

  1. 硬编码XML文件名:脚本固定解析LLL_ABC0D012_title.xml,未处理循环到的当前XML文件,导致提取的num与实际操作文件不匹配。
  2. where方法使用错误:table2['dtp1'].where(...)会返回完整Series,仅保留匹配位置的值,其余设为NaN,无法直接获取单个匹配值。
  3. 固定索引访问XML元素风险高:用root[8]、root[9]这种索引定位标签,XML结构变化就会失效,应按标签名查找。
  4. 硬编码输出文件名:写入时固定用LLL_ABC0D012_title.xml,会覆盖原文件且无法处理其他XML。

修复后的脚本

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

# 读取Excel并构建快速匹配的字典映射
table = pd.read_excel('C:/Users/Documents/datatypes.xlsx', na_values=['NA'])
table = table.replace('\xa0', ' ', regex=True)
# 将reference设为索引,转成字典,后续通过键直接取值,效率更高
ref_map = table.set_index('reference')[['dtp1', 'dtp2', 'dtp3']].to_dict('index')

# 遍历所有XML文件
for root_dir, _, files in os.walk("."):
    for file in files:
        if file.endswith('.xml'):
            # 提取文件名中LLL_后的8位字符
            if len(file) >= 12 and file.startswith('LLL_'):
                num = file[4:12]
                # 检查是否存在匹配的reference
                if num in ref_map:
                    dtp_values = ref_map[num]
                    # 解析当前XML文件(拼接完整路径)
                    xml_path = os.path.join(root_dir, file)
                    tree = ET.parse(xml_path)
                    xml_root = tree.getroot()
                    
                    # 按标签名查找并替换文本
                    dtp1_elem = xml_root.find('dtp1')
                    if dtp1_elem is not None:
                        dtp1_elem.text = dtp_values['dtp1']
                    
                    dtp2_elem = xml_root.find('dtp2')
                    if dtp2_elem is not None:
                        dtp2_elem.text = dtp_values['dtp2']
                    
                    dtp3_elem = xml_root.find('dtp3')
                    if dtp3_elem is not None:
                        dtp3_elem.text = dtp_values['dtp3']
                    
                    # 保存修改后的XML(覆盖原文件,如需保留原文件可修改文件名)
                    ET.indent(xml_root)
                    tree.write(xml_path, encoding='utf-8', xml_declaration=True, method='xml')
                else:
                    print(f"未找到匹配的reference:{num},文件:{file}")
            else:
                print(f"文件名格式不符合要求:{file}")

关键优化说明

  • 将Excel的reference设为索引并转成字典,匹配时直接通过键取值,比循环查找效率高,适合900+行的数据集。
  • 用file.endswith('.xml')替代file[-4:] == '.xml',更简洁可靠。
  • 用os.path.join拼接完整文件路径,避免子目录下的文件路径错误。
  • 添加格式检查和存在性判断,避免因文件名错误或无匹配数据导致崩溃,同时输出提示便于排查。
  • 用find()按标签名查找元素,避免XML结构变化导致的索引错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:50:11