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

C# DataSet.ReadXml读取XML时重复节点被跳过未存入问题

问题原因

DataSet.ReadXml() 方法会根据XML节点的出现规律自动推断关系型结构:

  • 同级下仅出现1次的子节点,会被映射为父级节点对应表的普通列
  • 同级下重复出现的同名子节点,不会被当成父表列,而是会被推断为独立的关联子表,通过自动生成的主键/外键和父表关联
    你遇到的“节点被跳过”本质是找错了存储位置,重复的ProductionSpecificationText节点值并没有丢失,只是存在自动生成的独立子表中。
验证方法

运行以下代码可以直接查看DataSet生成的所有表,确认数据位置:

DataSet dataSet = new DataSet();
dataSet.ReadXml(@"C:\Users\elhammh\Desktop\xmlfiletest");

// 打印DataSet内所有表的信息
foreach (DataTable table in dataSet.Tables)
{
    Console.WriteLine($"表名:{table.TableName},数据行数:{table.Rows.Count}");
    // 打印列名
    foreach (DataColumn col in table.Columns)
    {
        Console.WriteLine($"  列名:{col.ColumnName}");
    }
}

执行后你会看到DataSet内共生成2张表:

  • Production表:共1行数据,存储Number、Code、VehicleID、ModelID、Date这类非重复节点值,同时会自动生成Production_Id这类主键字段用于关联
  • ProductionSpecificationText表:共7行数据,就是你写入的7个重复配置节点值,通过外键字段和Production表关联
自定义读取方案(不拆子表)

如果你不需要关联子表结构,希望把重复节点的值直接合并存入主表,可以先手动定义DataTable结构,再通过LINQ to XML读取填充,避免默认结构推断的拆分逻辑:

DataSet dataSet = new DataSet();
DataTable prodTable = new DataTable("Production");

// 手动定义表结构
prodTable.Columns.Add("Number", typeof(string));
prodTable.Columns.Add("Code", typeof(string));
prodTable.Columns.Add("VehicleID", typeof(string));
prodTable.Columns.Add("ModelID", typeof(string));
prodTable.Columns.Add("Date", typeof(DateTime));
prodTable.Columns.Add("ProductionSpecificationText", typeof(string));
dataSet.Tables.Add(prodTable);

// 读取XML手动填充数据
XDocument xDoc = XDocument.Load(@"C:\Users\elhammh\Desktop\xmlfiletest");
// 遍历所有Production节点(单节点/多节点场景都兼容)
foreach (XElement prodNode in xDoc.Root.Elements("Production"))
{
    DataRow row = prodTable.NewRow();
    row["Number"] = prodNode.Element("Number")?.Value?.Trim();
    row["Code"] = prodNode.Element("Code")?.Value?.Trim();
    row["VehicleID"] = prodNode.Element("VehicleID")?.Value?.Trim();
    row["ModelID"] = prodNode.Element("ModelID")?.Value?.Trim();
    if (DateTime.TryParse(prodNode.Element("Date")?.Value, out DateTime prodDate))
    {
        row["Date"] = prodDate;
    }
    // 拼接所有重复的ProductionSpecificationText节点值,分隔符可按需替换
    var specValues = prodNode.Elements("ProductionSpecificationText")
                            .Select(e => e.Value?.Trim())
                            .Where(v => !string.IsNullOrEmpty(v));
    row["ProductionSpecificationText"] = string.Join(",", specValues);
    
    prodTable.Rows.Add(row);
}

如果你需要保留多值的结构化存储,直接读取自动生成的ProductionSpecificationText子表数据即可,不需要额外写解析逻辑,通过表间关联就能拿到对应Production记录下的所有配置值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:24:28