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

DataSet因子表同名导致XML数据在DataGridView1中显示异常

解决DataSet读取XML时同名子表合并导致的数据显示问题

DataSet默认会根据XML元素名称推断表结构,当不同父节点下存在同名子元素(如示例中Gases和Actions下的Record)时,会将这些子元素合并到同一个DataTable中,导致无法直接通过子表名区分数据。以下是无需指定固定表名的通用解决方案:

修改后的核心代码

调整comboBox1_SelectedIndexChanged方法,利用DataSet自动生成的层级数据关系,精准获取对应父节点下的子数据:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (comboBox1.SelectedIndex == 0)
    {
        dataGridView1.DataSource = dataSet.Tables[comboBox1.SelectedIndex].DefaultView;
        return;
    }

    string parentTableName = comboBox1.Text;
    DataTable parentTable = dataSet.Tables[parentTableName];
    if (parentTable == null || parentTable.ParentRelations.Count == 0)
    {
        dataGridView1.DataSource = null;
        return;
    }

    // 获取父表与主表(Language)的关联关系
    DataRelation parentRelation = parentTable.ParentRelations[0];
    DataTable mainTable = parentRelation.ParentTable;
    if (mainTable.Rows.Count == 0)
    {
        dataGridView1.DataSource = null;
        return;
    }

    // 获取主表行对应的父表(Gases/Actions)行
    DataRow[] parentRows = mainTable.Rows[0].GetChildRows(parentRelation);
    if (parentRows.Length == 0)
    {
        dataGridView1.DataSource = null;
        return;
    }
    DataRow parentRow = parentRows[0];

    // 获取父表与子表(Record)的关联关系
    if (parentRow.Table.ChildRelations.Count == 0)
    {
        dataGridView1.DataSource = null;
        return;
    }
    DataRelation childRelation = parentRow.Table.ChildRelations[0];

    // 获取当前父节点下的所有Record子行
    DataRow[] childRows = parentRow.GetChildRows(childRelation);
    if (childRows.Length == 0)
    {
        dataGridView1.DataSource = null;
        return;
    }

    // 将子行转换为DataTable并绑定到DataGridView
    DataTable childTable = childRows.CopyToDataTable();
    dataGridView1.DataSource = childTable.DefaultView;
}

原理说明

  1. DataSet读取XML时会自动生成层级关联关系:主表Language与Gases、Actions分别存在关联,Gases、Actions又各自与Record存在关联。
  2. 通过ParentRelations获取父表(Gases/Actions)与主表的关联,再通过GetChildRows拿到主表对应的父表行。
  3. 接着通过父表的ChildRelations获取与Record的关联,再次调用GetChildRows拿到当前父节点下的所有Record数据,避免直接读取合并后的Record表。

可选优化(固定结构场景)

如果XML结构固定,可以通过自定义XSD Schema让DataSet直接生成不同的子表名(如GasesRecord、ActionsRecord)。示例XSD片段:

<xs:element name="Gases">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Record" type="RecordType" maxOccurs="unbounded" table="GasesRecord"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="Actions">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Record" type="RecordType" maxOccurs="unbounded" table="ActionsRecord"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

读取时先加载Schema再读取XML:

dataSet.ReadXmlSchema("your-schema.xsd");
dataSet.ReadXml(xmlFile);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:54:56