2009-04-23 7 views
17

Je suis en train de créer un schéma pour un élément <property> qui doit avoir un sous-élément <key>, et l'un des <val>, <shell> ou <perl> et un <os> ou <condition> en option, et l'ordre des sous-éléments n'a pas d'importance .Schéma XML: Pourquoi ne pas <xs:all> avoir <choice> enfants? et comment cela peut-il être contourné?

Voici quelques échantillons pour <property> valides éléments:

<property> 
    <key>A</key> 
    <val>b</val> 
</property> 

<property> 
    <key>A</key> 
    <val>b</val> 
    <os>Windows</os> 
</property> 

<property> 
    <condition>a == 1</condition> 
    <key>A</key> 
    <perl>1+1</perl> 
    <os>unix</os> 
</property> 

Idéalement, je pensais à l'aide <xs:all> pour cela:

<xs:element name="property"> 
    <xs:complexType> 
    <xs:all> 
     <xs:element name="key" type="xs:string" /> 
     <xs:choice> 
     <xs:element name="val" type="xs:string" /> 
     <xs:element name="perl" type="xs:string" /> 
     <xs:element name="shell" type="xs:string" /> 
     </xs:choice> 
     <xs:element name="os" type="xs:string" minOccurs="0" /> 
     <xs:element name="condition" type="xs:string" minOccurs="0" /> 
    </xs:all> 
    </xs:complexType> 
</xs:element> 

Mais j'ai découvert que <xs:all> ne peut contenir que <xs:element> et non <xs:choice> . Quelqu'un peut-il expliquer pourquoi est-ce?

Plus important encore, quelqu'un peut-il fournir un moyen de valider un tel élément <property>?

je peux mettre les trois éléments - <val>, <perl> et <shell> - comme éléments facultatifs dans le <xs:all>, mais je veux le schéma pour valider que l'un et un seul des trois existe dans l'élément. Cela peut-il être fait?

+1

@splintor: Avez-vous réellement regardé la fenêtre de prévisualisation lorsque vous avez écrit votre question? Je veux dire, la moitié était invisible ... – Tomalak

+0

Voulez-vous dire que les deux os et la condition peuvent se produire dans le même élément de propriété ou que l'un ou l'autre ou aucun ne peut se produire? –

+0

@Tomalak: Non - J'ai raté cette fenêtre d'aperçu. Merci beaucoup de l'avoir édité pour signifier ce que je voulais. – splintor

Répondre

22

Je pense que cela est un peu mieux, comme le « choix » est maintenant son propre élément (typeFacet), mais ne peut pas être utilisé directement car il est abstrait.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="property"> 
    <xs:complexType> 
     <xs:all> 
     <xs:element name="key" type="xs:string" /> 
     <xs:element ref="typeFacet" /> 
     <xs:element name="os" type="xs:string" minOccurs="0" /> 
     <xs:element name="condition" type="xs:string" minOccurs="0" /> 
     </xs:all> 
    </xs:complexType> 
    </xs:element> 

    <xs:element name="typeFacet" abstract="true" /> 
    <xs:element name="val" type="xs:string" substitutionGroup="typeFacet" /> 
    <xs:element name="perl" type="xs:string" substitutionGroup="typeFacet" /> 
    <xs:element name="shell" type="xs:string" substitutionGroup="typeFacet" /> 
</xs:schema> 
+0

oui, c'est une amélioration. – 13ren

+0

Oui, c'est exactement ce que je voulais dire, mais c'était trop fait pour le faire. L'abstraction est certainement une bonne idée ici aussi. –

+0

Super, je ne savais pas sur la substitution dans le schéma XSD. Cela semble faire ce dont j'ai besoin. Merci. – splintor

6

Basé sur le commentaire de triton sur l'utilisation des groupes de substitution pour le choix (testé avec xmllint):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="property"> 
    <xs:complexType> 
     <xs:all> 
     <xs:element name="key" type="xs:string" /> 
     <xs:element ref="val"/> 
     <xs:element name="os" type="xs:string" minOccurs="0" /> 
     <xs:element name="condition" type="xs:string" minOccurs="0" /> 
     </xs:all> 
    </xs:complexType> 
    </xs:element> 

    <xs:element name="val" type="xs:string"/> 
    <xs:element name="perl" type="xs:string" substitutionGroup="val" /> 
    <xs:element name="shell" type="xs:string" substitutionGroup="val" /> 
</xs:schema> 
+0

Génial, je ne connaissais pas la substitution dans le schéma XSD. Cela semble faire ce dont j'ai besoin. Merci. – splintor

Questions connexes