La formulazione alternativa della domanda aggiunta in una modifica successiva sembra essere ancora senza risposta: come specificare che tra i figli di un elemento deve essercene uno con nome child3
, uno con nome child4
e un numero qualsiasi child1
o child2
, senza vincoli sull'ordine in che appaiono i bambini.
Si tratta di un linguaggio regolare definibile in modo semplice e il modello di contenuto necessario è isomorfo a un'espressione regolare che definisce l'insieme di stringhe in cui le cifre "3" e "4" ricorrono ciascuna esattamente una volta e le cifre "1" e "2" 'si verificano un numero qualsiasi di volte. Se non è ovvio come scriverlo, può essere utile pensare a quale tipo di macchina a stati finiti costruiresti per riconoscere tale linguaggio. Avrebbe almeno quattro stati distinti:
- uno stato iniziale in cui non è stato visto né "3" né "4"
- uno stato intermedio in cui è stato visto "3" ma non "4"
- uno stato intermedio in cui è stato visto "4" ma non "3"
- uno stato finale in cui sono stati visti sia "3" che "4"
Indipendentemente dallo stato in cui si trova l'automa, è possibile leggere "1" e "2"; non modificano lo stato della macchina. Nello stato iniziale verranno accettati anche "3" o "4"; negli stati intermedi si accetta solo "4" o "3"; nello stato finale, né "3" né "4" sono accettati. La struttura dell'espressione regolare è più facile da capire se definiamo prima una regex per il sottoinsieme della nostra lingua in cui si verificano solo "3" e "4":
(34)|(43)
Per consentire a "1" o "2" di verificarsi un numero qualsiasi di volte in una determinata posizione, possiamo inserire (1|2)*
(o [12]*
se il nostro linguaggio regex accetta quella notazione). Inserendo questa espressione in tutte le posizioni disponibili, otteniamo
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Tradurre questo in un modello di contenuto è semplice. La struttura di base è equivalente alla 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>
L'inserimento di una scelta zero o più di child1
ed child2
è semplice:
<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>
Se vogliamo minimizzare un po 'il volume, possiamo definire un gruppo denominato per le scelte ripetute di child1
e 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>
In XSD 1.1, alcuni dei vincoli sui all
gruppi sono stati rimossi, quindi è possibile definire questo modello di contenuto in modo più conciso:
<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>
Ma come si può vedere dagli esempi forniti in precedenza, queste modifiche a all
-gruppi di fatto non cambiano la forza espressiva del linguaggio; rendono solo più succinta la definizione di certi tipi di lingue.