为什么在添加 maxOccurs 指示器时,此 xml 架构对 .NET DataSet 无效?

Why does this xml schema become invalid for a .NET DataSet when adding the maxOccurs indicator?

提问人:alexandre gravel 提问时间:11/14/2023 最后编辑:alexandre gravel 更新时间:11/16/2023 访问量:73

问:

将下面的 xml 传递给 C# 程序中的 DataSet.ReadXml 函数时(使用 .NETFramework v4.8),该函数会抛出一个异常,指示 的声明是重复的(“重复的声明 'foo'”)。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 指标会以某种方式删除错误。即此 XML 被函数接受

<?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>

如果这个版本有效,为什么以前的版本无效?

我尝试阅读 Microsoft 的函数文档,但我没有找到任何似乎相关的内容。

我还尝试更改maxOccurs的值。仅当使用默认值 1 时,才接受 xml。

当然,更改其中一个的名称将删除错误并保留 maxOccurs,但这并不能回答为什么会出现错误的问题。另外,我很想知道是否有不同的解决方法。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
         {
            //Throws if given a file containing the first schema example
            ds.ReadXml(ofd.FileName);
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message);
         }
      }
   }
}
C# XML XSD

评论

0赞 Yitzhak Khabinsky 11/14/2023
在提出 XSD 问题时,您需要提供一个最小的可重现示例:(1) 格式正确的输入 XML。(2)你的逻辑,以及试图实现它的完整XSD。(3) XSD 处理器及其与 XSD 标准的一致性:1.0 或 1.1。(4) C# 验证码。
0赞 Charlieface 11/14/2023
如果 是无界的,那么解析器如何知道 a 是否来自 or ?maxOccursfooATypeBType
1赞 mamift 11/14/2023
您收到的错误消息的实际文本是什么?不要截断或重新措辞,只需逐字复制和粘贴即可。
1赞 Charlieface 11/14/2023
DataSet 适用于具有关系的 ADO.Net 表集。对于泛型 XSD 验证,请使用 和/或 Linq2XML learn.microsoft.com/en-us/dotnet/standard/linq/validate-xsdXmlReader
1赞 alexandre gravel 11/16/2023
@YitzhakKhabinsky 鉴于该问题与已经给出的内容完全可重现,并且我没有要提供的 xml 输入,我不会添加任何输入。

答:

0赞 Michael Kay 11/14/2023 #1

您提供的架构文档是有效的 XSD 架构,Saxon 接受它为有效架构。这个问题似乎是 Microsoft 的 DataSet 类中的一个限制。我在文档中看到以下注释:

如果 DataSet 的架构包含同名元素,但 不同的类型,在同一个命名空间中,当你 尝试使用 ReadXml 将架构读入 DataSet,方法是指定 XmlReadMode.ReadSchema。如果使用 .NET Framework 1.0 版。

我不知道你是如何解决这个问题的:这取决于你想在你的项目中实现什么,以及你为什么选择这种特定的技术来实现它。

评论

0赞 alexandre gravel 11/14/2023
虽然问题可能确实是此架构不适合 DataSet,但我不确定文档引用是否适用于这种情况。异常消息指示为重复的元素共享相同的名称相同的类型。