2008-10-16 59 views
4

我有點重複這個問題位第一次它被錯誤地問。XSD和多態性

我有這樣的:

<xsd:complexType name="A"> 
     <xsd:sequence> 
      <xsd:element name="options" type="options"/> 
     </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="B"> 
    <xsd:complexContent> 
      <xsd:element name="options" type="ex_options"/> 
    </xsd:complexContent> 
</xsd:complexType> 

<xsd:complexType name="options"> 
    <xsd:sequence> 
     ...some options 
    </xsd:sequence> 
</xsd:element> 

<xsd:complexType name="ex_options"> 
    <xsd:complexContent> 
     <xsd:extension base="options"> 
      <xsd:sequence> 
       ...some more options 
       </xsd:sequence> 
      </xsd:extension> 
    </xsd:complexContent> 
</xsd:element> 

所以基本上我有A類有一個內部類的選項 B類從A類繼承,我想B.options從A.options繼承這樣,當我們做web服務我們只需要傳遞一個,當我們調用getOptions時,它將返回正確的對象B.options。目前,使用xsd的方式,我得到一個錯誤,說明模型組中出現多個具有不同類型名稱選項的元素。錯誤是B類型的。

+0

你的榜樣XSD不是格式良好的(不包括...某些選項條目)。我認爲這是你嘗試過的一個例子。閱讀下面的回覆,我現在就明白了。你看起來想要的是兩個類,其中B擴展了A,而B的內容擴展了A的內容。 – 2008-10-16 16:48:19

回答

0

你可以使options序列開放式的,所以你可以有任意數量的選項,然後驗證基於屬性值的現有選項。例如,在下面的架構中,options列表具有type屬性要麼AB,說明哪些選項應該真正獲得上市:

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xs" 
        elementFormDefault="qualified" 
        xmlns="http://tempuri.org/XMLSchema.xs" 
        xmlns:mstns="http://tempuri.org/XMLSchema.xs" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <!-- Elements for document structure. --> 
    <!-- This section is just for validating my example file to --> 
    <!-- demonstrate the schema. --> 
    <xs:element name="root"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="elementA" type="A" minOccurs="0" maxOccurs="unbounded"/> 
     <xs:element name="elementB" type="A" minOccurs="0" maxOccurs="unbounded"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 



    <!-- The important part of the schema. --> 
    <!-- Types --> 
    <!-- A has options of type options. --> 
    <xs:complexType name="A"> 
    <xs:sequence> 
     <xs:element name="options" type="options"/> 
    </xs:sequence> 
    </xs:complexType> 

    <!-- Options specifies a options with a type attribute specifying which options will be available. --> 
    <xs:complexType name="options"> 
    <xs:sequence> 
     <xs:element name="option" minOccurs="0" maxOccurs="unbounded"/> 
    </xs:sequence> 
    <xs:attribute name="type" use="optional" default="A"> 
     <xs:simpleType> 
     <xs:restriction base="xs:string"> 
      <xs:enumeration value="A"/> 
      <xs:enumeration value="B"/> 
     </xs:restriction> 
     </xs:simpleType> 
    </xs:attribute> 
    </xs:complexType> 

</xs:schema> 

這裏是XML此架構的一個例子。

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns="http://tempuri.org/XMLSchema.xs"> 
    <elementA> 
    <options type="A"> 
     <option>Test-A</option> 
     <option>Test2-A</option> 
    </options> 
    </elementA> 
    <elementB> 
    <options type="B"> 
     <option>Test-B</option> 
     <option>Test2-B</option> 
     <option>Test3-B</option> 
     <option>Test4-B</option> 
    </options> 
    </elementB> 
</root> 
4

只要堅持瓦特/ B類型的元素,然後使用隨後裝飾你實例文檔元素如下所述瓦特/適當的xsi:type屬性值


<xsd:complexType name="B">

  <xsd:complexContent>
    <xsd:element name="options" type="ex_options"/>
  </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="options">
  <xsd:sequence>
      ...some options
  </xsd:sequence>
</xsd:element>

<xsd:complexType name="ex_options">
  <xsd:complexContent>
    <xsd:extension base="options">
      <xsd:sequence>
          ...some more options
      </xsd:sequence>
    </xsd:extension>
  </xsd:complexContent>
</xsd:element>

和然後「裝飾」您的實例元素爲

<options xsi:type="ex_options">...     (this will work)

<options xsi:type="options">...     (I think you can do this as long as the base xsi:type is not abstract)

如果事實證明你不能裝飾瓦特/底座XSI:類型, 那麼你可以隨時「欺騙」通過創建一個空的基本類型和然後 延長仔細建設,以達到您的兩個所需的格式。

更多的闡述&鏈接查看this post

0

您也可以使用限制,而不是擴展,但它不是最好的解決辦法,因爲限制刪除所有基本定義。更好的情況是在運行時使用xsi:type(在元素的XML實例中),如其他答案中所述。使用XSI的
更多了一個例子:類型是在這裏:http://www.xfront.com/ElementHierarchy.html

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<!-- Root element --> 
<xsd:element name="root" type="B"/> 

<!-- Base abstract type --> 
<xsd:complexType name="A" abstract="true"> 
    <xsd:sequence> 
    <!-- Option that we will override --> 
    <xsd:element name="options" type="options"/> 
    </xsd:sequence> 
</xsd:complexType> 

<!-- Derived type --> 
<xsd:complexType name="B"> 
    <xsd:complexContent> 
    <!--Overriding --> 
    <xsd:restriction base="A"> 
    <xsd:sequence> 
    <xsd:element name="options" type="ex_options"/> 
    </xsd:sequence> 
    </xsd:restriction> 
    </xsd:complexContent> 
</xsd:complexType> 

<!-- Base included class --> 
<xsd:complexType name="options"> 
    <xsd:sequence> 
    <xsd:element name="baseOption"/> 
    </xsd:sequence> 
</xsd:complexType> 

<!-- Overriding of included class --> 
<xsd:complexType name="ex_options"> 
    <xsd:complexContent> 
    <xsd:restriction base="options"> 
    <xsd:sequence> 
    <xsd:element name="overridedOption"/> 
    </xsd:sequence> 
    </xsd:restriction> 
    </xsd:complexContent> 
</xsd:complexType> 
</xsd:schema> 

在僞CiXML它會是這樣的:

{ 
    B root; 

    abstract class A 
    { 
    options options; 
    } 

    class B override A 
    { 
    ex_options options; 
    } 

    class options 
    { 
    empty baseOption; 
    } 

    class ex_option override options 
    { 
    empty overridedOption 
    } 
} 

下面的示例XML:

<?xml version="1.0" encoding="UTF-8"?> 
<root xsi:noNamespaceSchemaLocation="polymorphism.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <options> 
    <overridedOption/> 
    </options> 
</root>