将XSD 1.1模式转换为c#类

时间:2015-01-13 14:14:47

标签: c# .net xml xsd.exe xsd-1.1

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

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

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

1 个答案:

答案 0 :(得分: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>

(取自here的样本。这是估算您的特定模式是否可以在XSD 1.0中表达或转换为XSD 1.0的一个很好的起点。)

该示例显示了XSD 1.1中非常自然的继承用法。派生类型真正做的就是禁止成员tns:a。要在XSD 1.0中执行相同的操作,类型需要将tns:a列为maxOccurs='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实现。