答案在很大程度上取决于你想说什么部分,一部分对您所使用的模式语言:DTD的? XSD 1.0? XSD 1.1? RelaxNG?其他......?哦,对,我发现问题是标记为XSD,所以我假设你正在寻找一个XSD解决方案。
如果你想说的orderStatus
元素可以有要么序列orderId
,orderedBy
,或orderedOn
或儿童序列shipStatus
,而且属性shipStatus
和modifyShipStatus
是可选的,那么在这样说内容模型很简单。
在DTD符号(我在这里使用了它的紧凑性),你可以这样写:
<!ELEMENT orderStatus ((orderId, orderedBy, orderedOn) | shipStatus) >
<!ATTLIST orderStatus
shipStatus CDATA #IMPLIED
modifyShipStatus CDATA #IMPLIED
>
还是在XSD符号,写
<xs:element name="orderStatus" type="my:orderStatus"/>
<xs:complexType name="orderStatus">
<xs:choice>
<xs:sequence>
<xs:element ref="my:orderId"/>
<xs:element ref="my:orderedBy"/>
<xs:element ref="my:orderedOn"/>
</xs:sequence>
<xs:element ref="my:shipStatus"/>
</xs:choice>
<xs:attribute name="shipStatus"/>
<xs:attribute name="modifyShipStatus"/>
</xs:complexType>
然后你就大功告成了。
如果你想只允许两个属性中的一个,或者如果你想合法子女依赖于一个或另一个属性是否存在,事情更复杂。 (有些文档设计人员会说,如果你需要,你有两种截然不同的元素类型,你坚持用相同的名字来调用,这使得验证变得毫无困难。)
在这种情况下,你的选择是:
使用DTD和/或XSD架构1.0如上所述,并表达附加约束的文档中,或者使用Schematron的,或通过一些其它方法。
使用XSD 1.1,定义内容模型和如上所述的属性,并添加断言说属性shipStatus
的
- 恰好一个和
modifyShipStatus
必须出现。当且仅当出现一个名为orderId
孩子
- 属性
shipStatus
必须出现。当且仅当出现一个名为shipStatus
孩子
- 属性
modifyShipStatus
必须出现。
使用XSD 1。1,定义了两种不同类型的两种格式orderStatus
元素和使用条件类型分配说适用的类型时:
的XSD将是这个样子:
<xs:complexType name="orderStatus1">
<xs:sequence>
<xs:element ref="my:orderId"/>
<xs:element ref="my:orderedBy"/>
<xs:element ref="my:orderedOn"/>
</xs:sequence>
<xs:attribute name="shipStatus"/>
</xs:complexType>
<xs:complexType name="orderStatus2">
<xs:element ref="my:shipStatus"/>
<xs:attribute name="modifyShipStatus"/>
</xs:complexType>
<xs:element name="orderStatus">
<xs:alternative test="@shipStatus" type="my:orderStatus1"/>
<xs:alternative test="@modifyShipStatus" type="my:orderStatus2"/>
</xs:element>
- 我我们会顺便注意到,它的爱好者经常引用Relax NG的能力来制定这种限制作为其优势之一。