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

如何用ExcelDataReader读取Excel数据匹配文件名更新XML节点?

刚好之前做过类似的需求,用ExcelDataReader结合LINQ to XML就能搞定,我给你一步步拆解实现方法:

实现XML文件匹配XLSX字段并更新节点的方法(使用ExcelDataReader)

一、准备工作:安装依赖包

首先需要安装两个NuGet包,分别用于读取Excel和操作XML:

  • 读取Excel的核心包:ExcelDataReader
  • 辅助将Excel数据转为DataSet的包:ExcelDataReader.DataSet
  • .NET自带的System.Xml.Linq(一般无需额外安装,默认包含在项目中)

可以通过NuGet包管理器安装,或者用.NET CLI命令:

dotnet add package ExcelDataReader
dotnet add package ExcelDataReader.DataSet

二、核心实现步骤

1. 读取XLSX数据,构建文件名匹配字典

先把XLSX里的文件名、DOI、Publisher数据读出来,存成字典(文件名作为键),这样后续匹配XML文件时能快速查找对应数据:

using ExcelDataReader;
using System.Data;
using System.IO;
using System.Xml.Linq;
using System.Collections.Generic;

// 第一步:读取XLSX并构建匹配字典
var xlsxFilePath = @"C:\你的路径\数据文件.xlsx";
var xmlDataMap = new Dictionary<string, (string Doi, string Publisher)>();

// 注册编码(处理旧版Excel的编码问题,必须加这行)
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

using (var stream = File.Open(xlsxFilePath, FileMode.Open, FileAccess.Read))
{
    using (var reader = ExcelReaderFactory.CreateReader(stream))
    {
        // 配置读取规则:使用第一行作为表头
        var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration()
        {
            ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
            {
                UseHeaderRow = true
            }
        });

        // 假设数据在第一个工作表
        DataTable dataTable = dataSet.Tables[0];
        foreach (DataRow row in dataTable.Rows)
        {
            // 注意:这里要确保XLSX里的文件名和XML文件名完全匹配(包括后缀)
            // 如果XLSX里没有.xml后缀,就手动加上:fileName = $"{row["FileName"].ToString().Trim()}.xml"
            string fileName = row["FileName"].ToString().Trim();
            string doi = row["DOI"].ToString().Trim();
            string publisher = row["Publisher"].ToString().Trim();

            if (!string.IsNullOrEmpty(fileName))
            {
                xmlDataMap[fileName] = (doi, publisher);
            }
        }
    }
}

2. 遍历XML文件,匹配并更新节点

遍历指定文件夹下的所有XML文件,根据文件名从字典中取对应数据,更新或创建目标节点:

// 第二步:遍历XML文件夹,更新节点
var xmlFolderPath = @"C:\你的路径\XML文件夹";
foreach (var xmlFilePath in Directory.GetFiles(xmlFolderPath, "*.xml"))
{
    string xmlFileName = Path.GetFileName(xmlFilePath);
    if (xmlDataMap.TryGetValue(xmlFileName, out var targetData))
    {
        XDocument xmlDoc = XDocument.Load(xmlFilePath);
        // 处理XML命名空间(如果你的XML有默认命名空间,必须加这行,否则找不到节点)
        XNamespace defaultNs = xmlDoc.Root?.GetDefaultNamespace() ?? "";

        // 处理<publisher-name>节点:存在则更新,不存在则创建
        var publisherNode = xmlDoc.Descendants(defaultNs + "publisher-name").FirstOrDefault();
        if (publisherNode != null)
        {
            publisherNode.Value = targetData.Publisher;
        }
        else
        {
            // 这里假设要把节点添加到<front>下,你需要根据自己的XML结构调整父节点
            var frontNode = xmlDoc.Descendants(defaultNs + "front").FirstOrDefault();
            frontNode?.Add(new XElement(defaultNs + "publisher-name", targetData.Publisher));
        }

        // 处理<article-id pub-id-type="doi">节点:存在则更新,不存在则创建
        var doiNode = xmlDoc.Descendants(defaultNs + "article-id")
                            .FirstOrDefault(n => n.Attribute("pub-id-type")?.Value == "doi");
        if (doiNode != null)
        {
            doiNode.Value = targetData.Doi;
        }
        else
        {
            // 这里假设要把节点添加到<article-meta>下,根据实际XML结构调整
            var articleMetaNode = xmlDoc.Descendants(defaultNs + "article-meta").FirstOrDefault();
            articleMetaNode?.Add(new XElement(defaultNs + "article-id", targetData.Doi)
            {
                Attributes = { new XAttribute("pub-id-type", "doi") }
            });
        }

        // 保存修改后的XML文件
        xmlDoc.Save(xmlFilePath);
        Console.WriteLine($"已成功更新:{xmlFileName}");
    }
    else
    {
        Console.WriteLine($"未找到匹配数据,跳过:{xmlFileName}");
    }
}

三、关键注意事项

  • 命名空间处理:如果你的XML文件有默认命名空间,必须用XNamespace来定位节点,否则会出现“找不到节点”的问题。
  • 文件名匹配:确保XLSX中的文件名和XML文件名完全一致(包括后缀、大小写,Windows下不区分大小写,但Linux/macOS区分),不一致的话要提前做格式转换。
  • 节点位置调整:代码中假设了节点的父节点(比如<front>、<article-meta>),你需要根据自己的XML实际结构修改这些父节点的定位逻辑。
  • 异常处理:实际使用时建议添加try-catch块,处理文件被占用、XML格式错误等异常情况。
  • 空值处理:如果XLSX中DOI或Publisher为空,代码会写入空字符串,你可以根据需求添加判断,比如空值时不更新节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:54:24