2008-10-16 13 views
4

Je répète un peu ce bit question la 1ère fois il a été demandé de manière incorrecte.XSD et polymorphisme

je ceci:

<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> 

Donc, fondamentalement, j'ai la classe A avec une classe interne d'options classe B hérite de la classe A et je veux B.options à hériter de A.options de sorte que lorsque nous Pour les webservices, il suffit de passer un et quand nous appelons getOptions, il retournera le bon objet B.options. Actuellement avec la façon dont xsd se trouve, j'obtiens une erreur indiquant que plusieurs éléments avec des options de nom avec des types différents apparaissent dans le groupe de modèles. Les erreurs sont dans le type B.

+0

Votre exemple XSD n'est pas bien formé (à l'exception de ... l'entrée de certaines options). J'avais supposé que c'était un exemple de ce que tu as essayé. Ayant lu votre réponse ci-dessous je l'ai maintenant. ce que vous semblez vouloir, c'est deux classes où B étend A, et le contenu de B étend le contenu de A. –

+0

Bon, j'ai mis à jour ma réponse après vos commentaires. Merci. –

Répondre

0

Vous pourriez faire la séquence à composition non limitée options vous pouvez donc avoir un certain nombre d'options et valider les options existantes sur la base d'une valeur d'attribut. Par exemple, dans le schéma suivant, la liste options a un attribut type de l'une ou AB, ce qui indique quelles options devraient effectivement obtenir la liste:

<?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> 

Voici un exemple de XML pour ce schéma.

<?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

Tenez w/éléments de type B et ensuite utiliser puis décorer vos éléments de document d'exemple comme décrit ci-dessous w/xsi approprié: la valeur de l'attribut 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>

et puis "décorez" votre élément d'instance en tant que

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

ou

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

S'il se avère que vous ne pouvez pas décorer w/la base xsi: type, alors vous pouvez toujours "tricher" en créant un type de base vide et puis extension par une construction soignée pour arriver à vos deux formats souhaités.

Voir this post pour plus élaboration & liens.

0

Vous pouvez également utiliser la restriction plutôt que l'extension, mais ce n'est pas la meilleure solution, car la restriction supprime toutes les définitions de base. Le meilleur cas est l'utilisation de xsi: type à l'exécution (dans les instances XML d'éléments) comme décrit dans l'autre réponse.
Plus un exemple d'utilisation xsi: type est ici: 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> 

En pseudo CiXML ce sera quelque chose comme:

{ 
    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 
    } 
} 

Voici le code XML exemple:

<?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>