Альтернативная формулировка вопроса, добавленная в более позднем редактировании, кажется, все еще остается без ответа: как указать, что среди дочерних элементов элемента должен быть один именованный child3
, один именованный child4
и любое число с именем child1
или child2
, без ограничения на порядок в которые появляются у детей.
Это легко определяемый регулярный язык, и необходимая вам модель содержимого изоморфна регулярному выражению, определяющему набор строк, в которых каждая цифра 3 и 4 встречается ровно один раз, а цифры 1 и 2 'встречаются любое количество раз. Если не совсем понятно, как это писать, можно подумать, какой тип конечного автомата вы бы построили для распознавания такого языка. У него будет как минимум четыре различных состояния:
- исходное состояние, в котором не было видно ни «3», ни «4»
- промежуточное состояние, в котором было замечено «3», но не «4»
- промежуточное состояние, в котором было замечено «4», но не «3»
- конечное состояние, в котором были видны как '3', так и '4'
Независимо от того, в каком состоянии автомат находится, могут быть прочитаны «1» и «2»; они не меняют состояние машины. В исходном состоянии также принимаются цифры «3» или «4»; в промежуточных состояниях принимается только «4» или «3»; в конечном состоянии ни «3», ни «4» не принимаются. Структуру регулярного выражения легче всего понять, если мы сначала определим регулярное выражение для подмножества нашего языка, в котором встречаются только «3» и «4»:
(34)|(43)
Чтобы позволить «1» или «2» встречаться любое количество раз в данном месте, мы можем вставить (1|2)*
(или [12]*
если наш язык регулярных выражений принимает эту нотацию). Вставляя это выражение во все доступные места, мы получаем
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Преобразовать это в модель контента несложно. Базовая структура эквивалентна регулярному выражению (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>
Вставить ноль или более вариантов child1
и child2
просто:
<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>
Если мы хотим немного минимизировать объем, мы можем определить именованную группу для повторяющихся вариантов child1
и 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>
В XSD 1.1 all
были сняты некоторые ограничения на -groups, поэтому эту модель содержимого можно определить более кратко:
<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>
Но, как видно из примеров, приведенных ранее, эти изменения all
-группы на самом деле не меняют выразительную силу языка; они только делают определение некоторых языков более лаконичным.