将 XSD 1.1 模式转换为 c# class

Transform XSD 1.1 schema to c# class

我必须将 XSD 1.1 模式转换为 c# class。问题是 xsd.exe 不支持 XSD 1.1,事实上,如果我尝试从该模式创建 c# class,我会收到此错误:

通知验证方案:此上下文不支持元素“http://www.w3.org/2001/XMLSchema:assert”。

我该如何解决这个问题?

没有简单的方法解决这个问题。

自定义 xsd.exe 行为通常是可能的,甚至很容易。它只是 .NET 库 (System.Xml) 之上的一个薄层。但是那些库不理解 XSD 1.1,所以你必须有一个 XSD 1.0 文档来提供它们。如果您可以将模式转换为旧规范语言,那么您也可以使用未修改的 xsd.exe

您能否将 XSD 1.1 架构转换为 XSD 1.0 架构,以达到您的目的?在某些情况下,这可能很容易。例如,一个非常简单的 XSLT 转换可以过滤断言,用合适的 XSD 1.0 数据类型等替换新的数据类型。然而,一般情况介于困难和无法解决之间。让我们看看 XSD 1.1 在哪里添加了您不能忽略的功能:

<complexType name="base">
  <complexContent>
    <sequence>
      <element ref="tns:a" minOccurs="0" maxOccurs="1"/>
      <choice minOccurs="0" maxOccurs="unbounded">
        <element ref="tns:b"/>
        <element ref="tns:c"/>
      </choice>
    </sequence>
   </complexContent>
 </complexType>

<complexType name="derived">
  <complexContent>
    <restriction base="tns:base">
      <sequence>
        <choice minOccurs="0" maxOccurs="unbounded">
          <element ref="tns:b"/>
          <element ref="tns:c"/>
        </choice>
      </sequence>
    </restriction>
   </complexContent>
 </complexType>

(样本取自 here。这是一个很好的起点,用于估计您的特定模式是否可以用 XSD 1.0 表示或转换为 XSD 1.0。)

示例显示了 XSD 1.1 中继承的非常自然的用法。派生类型真正做的就是禁止成员tns:a。要在 XSD 1.0 中做同样的事情,类型需要列出 tns:amaxOccurs='0',并且相应的 C# class 包含 a 成员,无论您是否需要。这样的降级转换(从 XSD 1.1 到 XSD 1.0)仍然相对容易组合起来为这个简单的示例提供服务,但是当您需要在整个继承层次结构中映射具有这种受限可选的粒子时,基本上是不可能的成员 and/or 通配符。 XSD 1.0 的表现力不够。

现在回答一般性问题。假设您的架构事先未知 and/or 大量使用新的 XSD 1.1 功能。您将无法将它们转换为 XSD 1.0,因此 .NET 基础 class 库不会帮助您从它们生成 C# classes。您还有两个或三个选项:

  • 您可以手动创建反序列化 classes。您将无法验证和反序列化,但您将能够反序列化有效文档,包括强制执行正确的属性默认值(您希望保留的典型验证副作用)。
  • 您可以创建自己的 XSD 1.1 解析支持。一个非常大的项目,尽管您可以忽略很多模式(例如断言的整个 XSLT 2.0 规范)并且仍然能够以有点自然的 C# classes 结束。
  • 您可以使用具有此功能的现有第三方库。我怀疑目前可供选择的空集。 Saxon 的 API 不会从模式中生成反序列化 classes。而且我不知道 .NET 平台上还有任何其他 XSD 1.1 实现。