2009-01-06 13 views
17

Ceci est une question de schéma XML.XSD - Comment décrire un ensemble non ordonné de types d'éléments où le premier élément doit apparaître en premier dans la séquence?

Je sais que l'élément xsd:all ne peut pas apparaître dans une séquence (doit être l'élément de premier niveau de son type).

C'est, je ne peux pas utiliser les éléments suivants:

<xsd:complexType name="Application"> 
    <xsd:sequence> 
    <xsd:element ref="Name"></xsd:element> 
    <xsd:all> 
     <xsd:element ref="ADD"></xsd:element> 
     <xsd:element ref="DELETE"></xsd:element> 
    </xsd:all> 
    </xsd:sequence> 
</xsd:complexType> 

Ma question est de savoir comment déclarer la « ADD » et éléments « SUPPR » ci-dessus dans un ordre quelconque (ensemble non ordonné) mais assurez-vous que l'élément "Nom" serait le premier et apparaît toujours. (Pensez à la situation où je n'ai pas seulement "ADD" et "DELETE" mais environ 10 éléments non ordonnés: ADD, DELETE, EDIT etc ...)

NOTE IMPORTANTE: les champs ADD et DELETE peuvent apparaître seulement UNE FOIS, mais leur ordre est peu importe:

<Application> 
    <NAME> 
    <DELETE> 
    <ADD> 
</Application> 

mais pas:

<Application> 
    <NAME> 
    <DELETE> 
    <ADD> 
    <DELETE> <!--cannot appear twice--> 
</Application> 

Répondre

17

Si je comprends votre demande, vous êtes sur la bonne voie, la seule chose que vous êtes absent est maxOccurs = « unbounded » à votre choix.

J'ai créé le schéma suivant:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://someNamespace" xmlns="http://someNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Root" type="Application"> 
    </xs:element> 

    <xs:complexType name="Application"> 
    <xs:sequence> 
     <xs:element ref="Name"></xs:element> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element ref="ADD"></xs:element> 
     <xs:element ref="DELETE"></xs:element> 
     </xs:choice> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:element name="Name"/> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
</xs:schema> 

Et cela a bien fonctionné pour

<ns0:Root xmlns:ns0="http://someNamespace"> 
    <ns0:Name /> 
    <ns0:ADD /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:DELETE /> 
</ns0:Root> 

mais pas pour

<ns0:Root xmlns:ns0="http://someNamespace"> 
    <ns0:ADD /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:DELETE /> 
</ns0:Root> 
+0

Merci beaucoup pour votre réponse. J'ai bien réglé ma question ci-dessus. Je voulais dire que ADD et DELETE ne devraient pas apparaître 0 ou 1 fois, mais leur ordre n'est pas important. "all" ne peut pas être utilisé dans ce cas, car l'élément obligatoire NAME ne peut pas être associé à "all". Avez-vous une autre solution? Merci – ogee

+0

Cela fonctionne uniquement avec l'attribut maxOccurs = "unbounded" pour la balise de choix – Pooya

3

Je ne crois pas que cela puisse se faire sans l'énumération Toutes les combinaisons de ADD, DELETE, etc. En règle générale, les listes non ordonnées ne fonctionnent pas bien, que ce soit avec des DTD ou des sc hémas.

+3

décrit une liste non ordonnée – lbalazscs

+0

@lbalazscs - De la question "NOTE IMPORTANTE: l'ADD et DELETE peut apparaître seulement une fois, mais leur ordre n'est pas important: ". maxOccurs = "unbounded" ne le fournira pas. – Alohci

+0

Alhoci, oui, l'OP voulait un SET non ordonné, mais les listes non ordonnées sont toujours possibles. J'ai ajouté ce commentaire, parce que j'ai été induit en erreur par votre réponse (j'ai eu un autre problème où les éléments pourraient apparaître n'importe quand), seulement pour découvrir plus tard que les listes non ordonnées sont absolument possibles. – lbalazscs

1

Vous pouvez implémenter des listes non ordonnées en utilisant le type de séquence xs:choice.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="Application"/> 
    <xs:complexType> 
    <xs:element name="NAME"> 
    <xs:sequence> 
    <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element name="ADD" type="xs:string"/> 
     <xs:element name="DELETE" type="xs:string"/> 
    </xs:choice> 
    </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
</xs:schema> 

De cette façon, vous restreignez l'utilisateur d'utiliser une étiquette qu'ils veulent à l'intérieur de l'élément <NAME/> mais leur permettent d'utiliser <ADD/> et <DELETE/> aussi souvent qu'ils le souhaitent.

+0

Est-ce que le '' est réellement nécessaire, dans ce cas? – LarsH

+1

@LarsH: Oui, car xs: choice ne permet que de choisir l'un des éléments listés. xs: sequence crée ici un choix illimité/répétable de ADD ou DELETE. Cependant, il ne répond pas à l'exigence du PO de ne jamais autoriser plus d'une instance de ADD et DELETE à la fois. –

4

Je suis désolé que vous avez travaillé avec ce problème depuis 7 ans maintenant avec aucune réponse. Je vais vous aider en revoyant vos hypothèses. En traitant "Nom" comme un élément de données qui doit être prioritaire, et en exigeant qu'il soit un enfant d'Application, puis en disant généralement que vous ne vous souciez pas de l'ordre de ses frères et soeurs, vous êtes faire une situation confuse pour vous. Pourquoi Name est-il un frère de ADD et DELETE s'il suit des règles différentes et sert un but différent? Si vous deviez modéliser ceci dans n'importe quelle autre structure de données, vous n'incluriez pas "Name" dans une liste de choses à côté de "ADD" et "DELETE". Vous diriez deux choses: Une application a un nom, et il a également une liste de commandes telles que ADD et DELETE.

Étant donné que Name est une chose spéciale par rapport à ADD et DELETE, il doit être modélisé séparément de ces autres balises. Ainsi, vous pouvez faire de Name un attribut d'Application et conserver Add et Delete en tant qu'éléments enfants, ou vous pouvez conserver Name en tant qu'élément enfant, puis entourer ADD et DELETE avec une balise de placeholder/grouping, telle que Commands . La balise Commands serait le seul frère de Name.

Voici un schéma prenant en charge le nom en tant qu'attribut, avec un nombre arbitraire de commandes dans n'importe quel ordre. "Nom comme Attribute.xsd":

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Application" type="Application_Type" /> 
    <xs:complexType name="Application_Type"> 
      <xs:all> 
       <xs:element minOccurs="0" ref="ADD"/> 
       <xs:element minOccurs="0" ref="DELETE"/> 
       <xs:element minOccurs="0" ref="THIRD"/> 
       <xs:element minOccurs="0" ref="FOURTH"/> 
      </xs:all> 
      <xs:attribute name="Name"/> 
    </xs:complexType> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
    <xs:element name="THIRD"/> 
    <xs:element name="FOURTH"/> 
</xs:schema> 

Exemple XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="text" xsi:noNamespaceSchemaLocation="Name as Attribute.xsd"> 
    <THIRD>text</THIRD> 
    <ADD>text</ADD> 
    <FOURTH>text</FOURTH> 
    <DELETE>text</DELETE> 
</Application> 

Et voici une avec les commandes imbriquées dans une balise d'espace réservé. "Commandes Grouping.xsd":

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Application" type="Application_Type"/> 
    <xs:complexType name="Application_Type"> 
     <xs:sequence> 
      <xs:element ref="Name"/> 
      <xs:element name="Commands" type="Commands_Type"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="Commands_Type"> 
     <xs:all> 
      <xs:element minOccurs="0" ref="ADD"/> 
      <xs:element minOccurs="0" ref="DELETE"/> 
      <xs:element minOccurs="0" ref="THIRD"/> 
      <xs:element minOccurs="0" ref="FOURTH"/> 
     </xs:all> 
    </xs:complexType> 
    <xs:element name="Name"/> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
    <xs:element name="THIRD"/> 
    <xs:element name="FOURTH"/> 
</xs:schema> 

Exemple XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Commands Grouping.xsd"> 
    <Name>text</Name> 
    <Commands> 
     <THIRD>text</THIRD> 
     <ADD>text</ADD> 
     <FOURTH>text</FOURTH> 
     <DELETE>text</DELETE> 
    </Commands> 
</Application> 

Une note sur l'un de ces messages est que zéro avec les commandes sont toujours message valide. Peut-être que c'est correct, mais si c'est un problème, peut-être que cette validation appartient à la couche Application plutôt qu'à la XSD.