2009-10-21 12 views
9

J'essaie de développer un schéma qui va valider certains fichiers XML existants dont j'ai hérité. J'aimerais que le schéma fasse autant de travail de validation que possible. Le défi est que les attributs et les éléments dépendent des valeurs des autres attributs.Création d'un schéma XML avec des attributs et des éléments subordonnés à d'autres attributs

Les données réelles sont assez abstraites, j'ai donc créé quelques exemples simples. Disons que j'ai les fichiers XML suivants:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature type="human" nationality="British"> 
    <Address>London</Address> 
</Creature> 

<?xml version="1.0" encoding="UTF-8"?> 
<Creature type="animal" species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 

Si « type » est « humaine » de la créature, je vais avoir un attribut « nationalité » et un élément enfant « Adresse ». Si le "type" de la créature est "animal", j'aurai un attribut "espèce" et un élément enfant "Habitat". Aux fins de cet exemple, un «humain» avec une «espèce» ou un «habitat» serait invalide - tout comme un «animal» avec une «nationalité» ou une «adresse». Si "Créature" n'était pas l'élément racine, je pourrais probablement avoir deux choix différents de "Créatures" en dessous de l'élément racine, mais je ne vois pas comment je peux faire cela quand "Créature" est l'élément racine. .

Est-il possible de créer un schéma pour ces fichiers qui ne correspondrait qu'à des documents valides? Si oui, comment pourrais-je m'y prendre?

Répondre

7

Vous pouvez utiliser l'attribut xsi: type à cette fin (vous devrez utiliser le type xsi: de l'espace de noms de l'instance XMLSchema plutôt que votre propre espace de noms sinon cela ne fonctionnera pas).

Dans le schéma, vous déclarez un type de base déclaré comme abstrait et créez des types complexes supplémentaires pour chaque sous-type (avec les éléments/attributs spécifiques à ce type). Sachez que pendant que cette solution fonctionne, il vaudrait mieux utiliser des noms d'éléments différents pour chaque type (le type xsi: va à l'encontre du grain car c'est maintenant l'attribut type en combinaison avec le nom de l'élément définit le type plutôt que simplement le nom de l'élément).

par exemple:

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<xs:element name="Creature" type="CreatureType"> 
</xs:element> 

    <xs:complexType name="CreatureType" abstract="true"> 
    <!-- any common validation goes here --> 
    </xs:complexType> 

    <xs:complexType name="Human"> 
    <xs:complexContent> 
     <xs:extension base="CreatureType"> 
     <xs:sequence maxOccurs="1"> 
      <xs:element name="Address"/> 
     </xs:sequence> 
     <xs:attribute name="nationality" type="xs:string"/> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="Animal"> 
    <xs:complexContent> 
     <xs:extension base="CreatureType"> 
     <xs:sequence maxOccurs="1"> 
      <xs:element name="Habitat"/> 
     </xs:sequence> 
     <xs:attribute name="species" type="xs:string"/> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

</xs:schema> 

Ce schéma validera ces deux:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Human" 
      nationality="British"> 
    <Address>London</Address> 
</Creature> 

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Animal" 
      species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 

mais pas:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="SomeUnknownThing" 
      something="something"> 
    <Something>Something</Something> 
</Creature> 

ou ceci:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Human" 
      species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 
+1

Merci pour la réponse très précise et excellent exemple dans votre solution. Vous venez de me sauver des heures de recherche sur Internet –

+1

Bon exemple! Pourriez-vous expliquer pourquoi 'xsi: type' fonctionne alors que' type' ne figure pas dans les fichiers XML? – Praetorian

+0

Excellent paradigme! Mais dans ma spécification de niveau de jeu XML, * I * veut spécifier la spécification, et non XML Schema (un je préfère "type" et pas "xsi: type"). Alors, est-ce une faiblesse du schéma XML? – Chameleon

Questions connexes