我必须将XSD 1.1架构转换为c#类。问题是xsd.exe不支持XSD 1.1,实际上如果我尝试从该模式创建一个c#类,我会收到此错误:
通知验证方案:此上下文中不支持元素“http://www.w3.org/2001/XMLSchema:assert”。
我怎样才能解决这个问题?
答案 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#类。您还剩下两个或三个选项: