Учитывая расположение XML как это, я пытаюсь создать схему XSD для проверки его.
<RootNode>
<ChildA />
<ChildC />
<ChildB />
<ChildB />
<ChildA />
</RootNode>
Требования следующие:
<xs:sequence>
неподходящий)Техника, которую я обычно использую для создания незаказанного списка узлов, состоит в том, чтобы использовать a <xs:choice maxOccurs="unbounded">
с каждым возможным узлом в списке, однако, я не могу создать minOccurs="1"
ограничение на ChildA и maxOccurs="1"
ограничение на ChildC. (# происшествий выбора имеет приоритет по тем из элементов здесь).
<xs:element name="RootNode">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="ChildA" minOccurs="1"/>
<xs:element name="ChildB" />
<xs:element name="ChildC" maxOccurs="1"/>
</xs:choice>
</xs:complexType>
</xs:element>
Update: В XSD 1.1m некоторые ограничения на all
-группы были сняты. См. ответы здесь и здесь.
Не самый простой вариант, но кажется выполнимым. Сложность здесь в том, что определения схем должны быть детерминированными. Подход, который я использовал, заключался в визуализации проблемы путем рисования конечного автомата состояний, а затем написания регулярного выражения, соответствующего этому автомату. Это совсем не так сложно, как может показаться. Тем не менее, использование какой-либо другой системы проверки, скорее всего, дало бы более простой ответ.
Я провел некоторое тестирование, но пропустить некоторые особые случаи очень легко. Пожалуйста, прокомментируйте, если вы заметили ошибку.
... и вот код:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<!-- Schema for elements ChildA, ChildB and ChildC
The requirements are as follows:
* ChildA, ChildB and ChildC may occur in any order.
* ChildA is mandatory but may occur multiple times.
* ChildB is optional and may occur multiple times.
* ChildC is optional and may occur once only.
-->
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ABC-container" type="ABC" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="ABC">
<xsd:sequence>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:sequence maxOccurs="1">
<xsd:element name="ChildC" type="xsd:string"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="ChildA" type="xsd:string"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
<xsd:sequence maxOccurs="1">
<xsd:element name="ChildA" type="xsd:string" minOccurs="1"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="ChildC" type="xsd:string"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
</xsd:sequence>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>