La formulation alternative de la question ajoutée dans une édition ultérieure semble toujours sans réponse : comment spécifier que parmi les enfants d'un élément, il doit y en avoir un nommé child3
un nommé child4
et tout nombre nommé child1
ou child2
sans aucune contrainte quant à l'ordre dans lequel les enfants apparaissent.
Il s'agit d'un langage régulier directement définissable, et le modèle de contenu dont vous avez besoin est isomorphe à une expression régulière définissant l'ensemble des chaînes de caractères dans lesquelles les chiffres "3" et "4" apparaissent chacun exactement une fois, et les chiffres "1" et "2" apparaissent un nombre quelconque de fois. Si la façon d'écrire ceci n'est pas évidente, il peut être utile de réfléchir au type de machine à états finis que vous construiriez pour reconnaître un tel langage. Elle aurait au moins quatre états distincts :
- un état initial dans lequel ni "3" ni "4" n'ont été vus.
- un état intermédiaire dans lequel "3" a été vu mais pas "4".
- un état intermédiaire dans lequel le "4" a été vu mais pas le "3".
- un état final dans lequel à la fois "3" et "4" ont été vus.
Quel que soit l'état de l'automate, '1' et '2' peuvent être lus ; ils ne changent pas l'état de la machine. Dans l'état initial, '3' ou '4' seront également acceptés ; dans les états intermédiaires, seuls '4' ou '3' sont acceptés ; dans l'état final, ni '3' ni '4' ne sont acceptés. La structure de l'expression régulière est plus facile à comprendre si nous définissons d'abord une regex pour le sous-ensemble de notre langue dans lequel seuls '3' et '4' apparaissent :
(34)|(43)
Pour permettre à '1' ou '2' de se produire un nombre quelconque de fois à un endroit donné, nous pouvons insérer (1|2)*
(ou [12]*
si notre langage regex accepte cette notation). En insérant cette expression à tous les endroits disponibles, on obtient
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
La transposition de ces données dans un modèle de contenu est simple. La structure de base est équivalente à la regex (34)|(43)
:
<xsd:complexType name="paul0">
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
Insertion d'un choix de zéro ou plus de child1
et child2
est simple :
<xsd:complexType name="paul1">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
Si nous voulons minimiser un peu l'encombrement, nous pouvons définir un groupe nommé pour les choix répétés de child1
et child2
:
<xsd:group name="onetwo">
<xsd:choice>
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="paul2">
<xsd:sequence>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
Dans la norme XSD 1.1, certaines des contraintes sur les fichiers all
-Les groupes ont été supprimés, de sorte qu'il est possible de définir ce modèle de contenu de manière plus concise :
<xsd:complexType name="paul3">
<xsd:all>
<xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:all>
</xsd:complexType>
Mais, comme le montrent les exemples donnés précédemment, ces changements de all
-En fait, les groupes ne modifient pas le pouvoir expressif de la langue ; ils ne font que rendre plus succincte la définition de certains types de langues.