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

为何为.NET DataSet的XML Schema添加maxOccurs后会失效?

.NET Framework 4.8中DataSet.ReadXml读取XML Schema时的重复声明异常问题

问题现象

在基于.NET Framework v4.8的C#程序中,使用DataSet.ReadXml读取以下XML Schema时,会抛出**"Duplicated declaration 'foo'"**异常:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="container" type="containerType"/>
  <xs:complexType name="containerType">
    <xs:sequence>
      <xs:element name="A" type="AType" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="B" type="BType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="AType">
    <xs:sequence>
      <xs:element name="foo" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="BType">
    <xs:sequence>
      <xs:element name="foo" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

但移除foo元素的maxOccurs属性(使用默认值1)后,该XML Schema可被正常读取:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="container" type="containerType"/>
  <xs:complexType name="containerType">
    <xs:sequence>
      <xs:element name="A" type="AType" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="B" type="BType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="AType">
    <xs:sequence>
      <xs:element name="foo" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="BType">
    <xs:sequence>
      <xs:element name="foo" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

疑问

已查阅微软官方文档未找到相关说明,尝试修改maxOccurs值仅默认值1时有效。重命名其中一个foo可解决问题,但想了解异常原因及其他可行方案。

附C#验证代码:

using System;
using System.Data;
using System.Windows.Forms;
static class Program
{
   static void Main()
   {
      OpenFileDialog ofd = new OpenFileDialog();
      if (ofd.ShowDialog() == DialogResult.OK)
      {
         var ds = new DataSet();
         try
         {
            // 传入第一个Schema文件时会抛出异常
            ds.ReadXml(ofd.FileName);
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message);
         }
      }
   }
}

异常原因

DataSet的XML Schema自动映射规则中:

  • 当元素设置maxOccurs="unbounded"时,该元素会被映射为独立的DataTable;
  • 当元素maxOccurs为默认值1(或显式设置为1)时,该元素会被映射为对应父DataTable中的DataColumn。

在第一个Schema中,AType和BType下的foo都设置了maxOccurs="unbounded",DataSet会尝试为这两个foo创建同名的DataTable。但DataSet不允许内部存在同名的DataTable(即使它们属于不同的父类型),因此触发"重复声明"的异常。

而第二个Schema中,foo的maxOccurs为默认1,此时foo会被分别映射到A表和B表中的列,不同DataTable的列名允许重复,因此不会产生冲突。

可行解决方案

  • 方案一:为同名 unbounded 元素指定唯一表名
    通过XML Schema的扩展注解msdata:TableName,给每个foo对应的DataTable指定唯一名称。需要先在schema根节点添加xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"命名空间,示例:

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
      <!-- 其他结构不变 -->
      <xs:complexType name="AType">
        <xs:sequence>
          <xs:element name="foo" type="xs:string" minOccurs="0" maxOccurs="unbounded">
            <xs:annotation>
              <xs:appinfo>
                <msdata:TableName>AFoo</msdata:TableName>
              </xs:appinfo>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="BType">
        <xs:sequence>
          <xs:element name="foo" type="xs:string" minOccurs="0" maxOccurs="unbounded">
            <xs:annotation>
              <xs:appinfo>
                <msdata:TableName>BFoo</msdata:TableName>
              </xs:appinfo>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
    
  • 方案二:调整Schema结构避免冲突
    比如将其中一个foo重命名,或者把重复的元素结构抽象为独立类型,再通过不同的元素名引用。

  • 方案三:手动构建DataSet结构
    跳过ReadXml的自动Schema映射,手动创建DataTable、DataColumn和表间关系,再读取XML数据填充DataSet,完全控制结构命名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:58:14