我必须将 XSD 1.1 模式转换为 c# 类。问题是 xsd.exe 不支持 XSD 1.1,事实上,如果我尝试从该架构创建一个 c# 类,我会收到以下错误:
通知验证方案:元素'注意验证方案:在此上下文中不支持 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>
(取自此处的示例。这是评估您的特定模式是否可以用 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# 类。您还有两个或三个选项: