2010-03-18 103 views
13

是否有可能以某種方式,以確定哪些可以驗證這種XML的XSD方案:如何在xsd:choice元素中定義幾個具有相同名稱但類型不同的元素?

<item_list> 
    <item ItemType="SimpleMessage" Caption="Simplest message"/> 
    <item ItemType="ComplexMessage" SomeAttr="value"> 
    <item_data>some text</item_data> 
    </item> 
</item_list> 

問題是,我沒有帶發現任何可能性來定義水木清華這樣的:

<xsd:element name="Items"> 
     <xsd:complexType> 
     <xsd:choice> 
      <xsd:element name="item" type="SimpleMessType"/> 
      <xsd:element name="item" type="ComplexMessType"/> 
     </xsd:choice> 
     </xsd:complexType> 
    </xsd:element> 

但我需要檢查,該SimpleMessage沒有子元素或額外attrs :(

回答

0

你不能這樣做使用您提出的架構結構,因爲該結構違反了XML架構模糊規則

您的一個潛在選擇是定義超類型,例如BaseElement,它是空的,然後是子類型,並使用xsi:type來覆蓋,而不僅僅是正常的type屬性。有關如何工作的更多信息可以參見here

5

XSD明確表示prohibits such a case。您必須將元素名稱更改爲唯一(或使用xsi:鍵入,因爲xcut表示,這相當於相同的東西)。

作爲變通,你可以合併類型定義SimpleMessTypeComplexMessType成一個單一類型混合=「真」 - 然後解開你的架構後,自己的代碼接收內容處理完成。請參閱關於XSD schema for recursive XML的計算器討論。

6

正如前面的答案已經提到的,你可以通過使用xsi:type屬性,而不是定義一個新ItemType屬性具有相同的功能做到這一點很容易足夠XSD 1.0。

XSD 1.1包含一個構造,旨在使支持這種情況的人更容易,因爲無論出於何種原因,不想以這種方式使用xsi:type:條件類型分配。從本質上講,它允許元素聲明具有簡單的XPath/typename對序列;將按順序評估XPath表達式,並在計算結果爲true時將元素與相應的類型關聯。對XPath有一些限制,禁止向前看元素的後代,或者查閱或瀏覽XML文檔的其他部分(第一次有助於瞭解,只要掃描遇到啓動標記,就會知道哪種類型的用於驗證一個元素;第二個有助於保持上下文無關),所以基本上測試只能是對屬性值的測試。您的例子可以寫成這樣:

<xs:element name="item"> 
    <xs:alternative test="@ItemType='SimpleMessage'" type="SimpleMessType"/> 
    <xs:alternative test="@ItemType='SimpleMessage'" type="ComplexMessType"/> 
    <xs:alternative type="xs:error"/> 
</xs:element> 

第三種方法可以確保您的預計情形之一的,必須遇到的元素是有效的。如果在這裏省略,那麼如果兩個測試表達式都不是真的,則該元素將被分配聲明的類型item,在這種情況下爲xs:anyType

相關問題