A formulação alternativa da questão adicionada em uma edição posterior parece ainda sem resposta: como especificar que entre os filhos de um elemento, deve haver um nomeado child3
, um nomeado child4
e qualquer número nomeado child1
ou child2
, sem restrição na ordem em que as crianças aparecem.
Esta é uma linguagem regular definida de forma direta, e o modelo de conteúdo de que você precisa é isomórfico a uma expressão regular que define o conjunto de strings em que os dígitos '3' e '4' ocorrem exatamente uma vez, e os dígitos '1' e '2 'ocorrer qualquer número de vezes. Se não for óbvio como escrever isso, pode ser útil pensar sobre que tipo de máquina de estado finito você construiria para reconhecer tal linguagem. Teria pelo menos quatro estados distintos:
- um estado inicial em que nem '3' nem '4' foi visto
- um estado intermediário em que '3' foi visto, mas não '4'
- um estado intermediário em que '4' foi visto, mas não '3'
- um estado final em que '3' e '4' foram vistos
Não importa em que estado o autômato esteja, '1' e '2' podem ser lidos; eles não mudam o estado da máquina. No estado inicial, '3' ou '4' também serão aceitos; nos estados intermediários, apenas '4' ou '3' é aceito; no estado final, nem '3' nem '4' é aceito. A estrutura da expressão regular é mais fácil de entender se primeiro definirmos um regex para o subconjunto de nossa linguagem em que apenas '3' e '4' ocorrem:
(34)|(43)
Para permitir que '1' ou '2' ocorra qualquer número de vezes em um determinado local, podemos inserir (1|2)*
(ou [12]*
se nossa linguagem regex aceitar essa notação). Inserindo esta expressão em todos os locais disponíveis, obtemos
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Traduzir isso em um modelo de conteúdo é simples. A estrutura básica é equivalente ao 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>
Inserir uma opção zero ou mais de child1
e child2
é simples:
<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 quisermos minimizar o volume um pouco, podemos definir um grupo nomeado para as opções de repetição de 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>
No XSD 1.1, algumas das restrições nos all
grupos foram eliminadas, então é possível definir este modelo de conteúdo de forma mais concisa:
<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>
Mas, como pode ser visto nos exemplos dados anteriormente, essas mudanças em all
grupos não alteram de fato o poder expressivo da linguagem; eles apenas tornam a definição de certos tipos de linguagens mais sucinta.