3

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

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

我怎样才能解决这个问题?

4

1 回答 1

1

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

自定义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>

(取自此处的示例。这是评估您的特定模式是否可以用 XSD 1.0 表示或转换为 XSD 1.0 的一个很好的起点。)

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

现在到一般问题。假设您的模式事先是未知的和/或大量使用新的 XSD 1.1 功能。您将无法将它们转换为 XSD 1.0,因此 .NET 基类库无法帮助您从它们生成 C# 类。您还有两个或三个选项:

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