2012-08-16 100 views
0

我想創建一個模式文件2個不同的XML的(我可以把它分成2種模式,但由於根元素是一樣的,我希望把它放在一個文件)。創建2種不同類型相同的根元素

現在我有2分不同的XML的。

<orderStatus shipStatus="SHIPPED/PENDING"> 
    <orderId>1234</orderId> 
    <orderedBy>userName</orderedBy> 
    <orderedOn>2012-07-23T11:35:51.000-04:00</orderedOn> 
</orderStatus> 

和第二XML是

<orderStatus modifyShipStatus="SUSPENDED/PENDING"> 
    <shipStatus>101</shipStatus> 
</orderStatus> 

如何可以有1個XSD這些2個XML?當我試圖創建一個1類型的根元素,它工作正常,但是當我嘗試添加另一種類型時,JAXB拋出錯誤,該元素已被定義。這使得sens。

回答

2

答案在很大程度上取決於你想說什麼部分,一部分對您所使用的模式語言:DTD的? XSD 1.0? XSD 1.1? RelaxNG?其他......?哦,對,我發現問題是標記爲XSD,所以我假設你正在尋找一個XSD解決方案。

如果你想說的orderStatus元素可以有要麼序列orderIdorderedBy,或orderedOn兒童序列shipStatus,而且屬性shipStatusmodifyShipStatus是可選的,那麼在這樣說內容模型很簡單。

在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的能力來制定這種限制作爲其優勢之一。
相關問題