2010-06-01 3 views
4

Prendre le véhicule XSD du W3C comme exemple:XML et XSD - Utiliser le nom de l'élément en remplacement de xsi: type pour polymorphisme

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://cars.example.com/schema" 
      xmlns:target="http://cars.example.com/schema"> 

    <complexType name="Vehicle" abstract="true"/> 

    <complexType name="Car"> 
    <complexContent> 
     <extension base="target:Vehicle"/> 
     ... 
    </complexContent> 
    </complexType> 

    <complexType name="Plane"> 
    <complexContent> 
     <extension base="target:Vehicle"/> 
     <sequence> 
     <element name="wingspan" type="integer"/> 
     </sequence> 
    </complexContent> 
    </complexType>  
</schema> 

, et la définition suivante de 'meansOfTravel':

<complexType name="MeansOfTravel"> 
    <complexContent> 
    <sequence>   
     <element name="transport" type="target:Vehicle"/>   
    </sequence> 
    </complexContent> 
</complexType> 

<element name="meansOfTravel" type="target:MeansOfTravel"/> 

Avec cette définition, vous devez spécifier le type de votre instance en utilisant xsi: type, comme celui-ci:

<meansOfTravel> 
    <transport xsi:type="Plane"> 
    <wingspan>3</wingspan> 
    </transport> 
</meansOfTravel> 

Je voudrais juste li ke atteind un « nom de type » - « nom de l'élément » mapping afin que cela pourrait être remplacé par tout

<meansOfTravel> 
    <plane> 
    <wingspan>3</wingspan> 
    </plane> 
</meansOfTravel> 

La seule façon que je pouvais le faire jusqu'à présent est en rendant explicite:

<complexType name="MeansOfTravel"> 
    <sequence>   
    <choice> 
     <element name="plane" type="target:Plane"/> 
     <element name="car" type="target:Car"/>   
    </choice> 
    </sequence> 
</complexType> 

<element name="meansOfTravel" type="target:MeansOfTravel"/> 

Mais cela signifie que je dois lister tous les sous-types possibles dans le type complexe 'MeansOfTravel'. Est-il impossible de faire en sorte que l'analyseur XML suppose que vous entendez un «plan» si vous appelez l'élément «plan»? Ou dois-je rendre le choix explicite? Je voudrais juste garder ma conception sèche - si vous avez d'autres suggestions (comme des groupes ou plus) - je suis tout ouïe.

Répondre

3

Il existe un modèle de conception commun, vous pouvez utiliser des sous-types (comme vous le faites déjà) et des éléments d'un groupe de substitution. Les éléments du groupe de substitution doivent être d'un sous-type de l'élément auquel ils sont substitués. Malheureusement, les éléments de groupe de substitution doivent être définis comme des éléments globaux. Vous auriez donc ceci:

<complexType name="MeansOfTravel"> 
    <complexContent> 
    <sequence>   
     <element ref="transport"/> 
    </sequence> 
    </complexContent> 
</complexType> 

<element name="transport" type="target:Vehicle"/> 
<element name="plane" type="target:Plane" substitutionGroup="target:transport"/> 

Ensuite, dans votre document XML, vous pouvez utiliser:

<meansOfTravel> 
    <plane>...</plane> 
</meansOfTravel> 

Plus d'informations sur les groupes de substitution here. Et non, malheureusement l'analyseur ne peut pas le deviner, il faut donc lister les éléments :(Il y a cependant un avantage sur un choix: le schéma peut être étendu en externe, en l'important, sans le modifier.

+1

Merci, cela semble bien, y a-t-il d'autres avantages à utiliser ce choix, sauf dans le cas de l'extension? Je demande parce que cela semble assez occupé, et je me demande si le choix serait plus logique –

+2

Si tout le schéma est sous votre contrôle, je choisirais entre autres choses, il rendra les classes générées en utilisant la liaison de données plus facile à lire, et évite d'introduire tous ces éléments globaux – xcut

+0

Ok Choix c'est.Merci encore. –

Questions connexes