La formulation alternative de la question ajoutée dans une édition ultérieure semble toujours être 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 n'importe quel nombre nommé child1
ou child2
, sans contrainte sur l'ordre dans que les enfants apparaissent.
Il s'agit d'un langage régulier clairement définissable, et le modèle de contenu dont vous avez besoin est isomorphe à une expression régulière définissant l'ensemble de chaînes dans lequel les chiffres '3' et '4' apparaissent chacun exactement une fois, et les chiffres '1' et '2 'se produisent un certain nombre de fois. Si la manière d'écrire cela 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. Il 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 '4' a été vu mais pas '3'
- un état final dans lequel les deux '3' et '4' ont été vus
Quel que soit l'état dans lequel se trouve l'automate, «1» et «2» peuvent être lus; ils ne modifient pas l'état de la machine. Dans l'état initial, «3» ou «4» sera également accepté; 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 la plus facile à comprendre si nous définissons d'abord une expression régulière pour le sous-ensemble de notre langage dans lequel seuls '3' et '4' apparaissent:
(34)|(43)
Pour permettre à '1' ou '2' de se produire un nombre illimité 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 emplacements disponibles, nous obtenons
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Traduire cela en un modèle de contenu est simple. La structure de base est équivalente à l'expression régulière (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>
Insérer un choix 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 le volume, 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 XSD 1.1, certaines des contraintes sur les all
groupes ont été levées, il est donc 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 on peut le voir d'après les exemples donnés précédemment, ces changements de all
groupes ne changent pas en fait le pouvoir expressif de la langue; ils ne font que rendre la définition de certains types de langues plus succincte.