答案在很大程度上取決於你想說什麼部分,一部分對您所使用的模式語言: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的能力來制定這種限制作爲其優勢之一。