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

如何避免大小写不同的XML属性在DataGridView中数据重复?

解决XML数据绑定DataGridView时ID列与id列数据重复的问题

我碰到过一模一样的坑!问题根源其实很简单:.NET里的DataTable和DataSet默认是不区分大小写的,当你的XML里同时存在小写id和大写ID这两个属性时,它们会被当成同一个字段处理,自然就会出现数据重复覆盖的情况。下面针对你用的两种方法,分别给出解决方案:

方法一:手动创建DataTable的修复方案

你之前的代码思路没问题,只是没开启DataTable的大小写敏感。只要在创建DataTable时加上CaseSensitive = true,就能让它区分"id"和"ID"两个列名,再配合安全的属性读取(避免空引用),就能正常显示数据了:

DataTable dt = new DataTable();
dt.CaseSensitive = true; // 关键:打开大小写敏感开关
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Severity", typeof(string));
dt.Columns.Add("id", typeof(string));
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("Msg", typeof(string));

XDocument docLog = XDocument.Load(XML_FILEPATH);
foreach (XElement log in docLog.Descendants("Log"))
{
    DateTime date = (DateTime)log.Attribute("Date");
    string severity = (string)log.Attribute("Severity");
    // 用?.Value ?? string.Empty处理属性不存在的情况,防止空引用异常
    string id = log.Attribute("id")?.Value ?? string.Empty;
    string ID = log.Attribute("ID")?.Value ?? string.Empty;
    string msg = log.Attribute("Msg")?.Value ?? string.Empty;
    dt.Rows.Add(new object[] { date, severity, id, ID, msg });
}

方法二:DataSet.ReadXml的修复方案

DataSet的自动Schema推断默认也不区分大小写,所以要么提前定义明确的XML Schema(XSD),要么手动创建区分大小写的DataTable再让DataSet读取。

方案A:用XSD Schema约束

先写一个和你的XML结构匹配的XSD文件(比如命名为LogSchema.xsd),明确区分id和ID两个属性:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Logging" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="Logging" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Log">
          <xs:complexType>
            <xs:attribute name="Date" type="xs:date" use="required" />
            <xs:attribute name="Severity" type="xs:string" use="required" />
            <xs:attribute name="id" type="xs:string" use="required" />
            <xs:attribute name="ID" type="xs:string" use="required" />
            <xs:attribute name="Msg" type="xs:string" use="optional" />
            <xs:attribute name="Pos" type="xs:string" use="optional" />
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

然后修改代码,先读取Schema再加载XML:

OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = @"XML files (*.xml)|*.xml|All files (*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    myLogfile = openFileDialog1.FileName;
    var dataset = new DataSet();
    dataset.CaseSensitive = true; // 开启大小写敏感
    // 先读取我们定义的Schema
    dataset.ReadXmlSchema(@"你的XSD文件路径\LogSchema.xsd");
    using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
    {
        dataset.ReadXml(sr);
    }
    var bindingSource = new BindingSource { DataSource = dataset, DataMember = "Log" };
    dataGridView1.DataSource = bindingSource;
}

方案B:手动创建DataTable加入DataSet

如果你不想写XSD,也可以先创建一个区分大小写的DataTable,添加到DataSet后再读取XML:

OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = @"XML files (*.xml)|*.xml|All files (*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    myLogfile = openFileDialog1.FileName;
    var dataset = new DataSet();
    dataset.CaseSensitive = true;
    
    // 手动创建区分大小写的Log表
    DataTable logTable = new DataTable("Log");
    logTable.CaseSensitive = true;
    logTable.Columns.Add("Date", typeof(DateTime));
    logTable.Columns.Add("Severity", typeof(string));
    logTable.Columns.Add("id", typeof(string));
    logTable.Columns.Add("ID", typeof(string));
    logTable.Columns.Add("Msg", typeof(string));
    logTable.Columns.Add("Pos", typeof(string)); // 兼容XML里的Pos属性
    dataset.Tables.Add(logTable);

    using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
    {
        // 忽略自动推断的Schema,用我们手动创建的表结构
        dataset.ReadXml(sr, XmlReadMode.IgnoreSchema);
    }
    var bindingSource = new BindingSource { DataSource = dataset, DataMember = "Log" };
    dataGridView1.DataSource = bindingSource;
}

两种方法都能解决你的问题,核心就是让DataTable/DataSet区分大小写,不再把id和ID当成同一个字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:19:09