Что вы можете сделать, так это сжать существующую модель содержимого в одну sequence
и пометить элементы Media
и label
как требуемые, а остальные как необязательные.
Причина нарушения правила UPA заключается в том, что правило работает с именем элемента и игнорирует тип данных и значение элемента. Вы можете объединить два значения элемента Media
( 12 дюймов , 7 дюймов ) в один тип union
и использовать его как тип элемента для <Media>
(я назвал его ' TwelveOrSevenIn 'ниже). Полная схема цитируется ниже:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="TwelveOrSevenIn">
<xs:restriction base="xs:string">
<xs:enumeration value="12in" />
<xs:enumeration value="7in" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MediaType">
<xs:sequence>
<xs:element name="Media" type="TwelveOrSevenIn" maxOccurs="1" minOccurs="1" />
<xs:element name="rpm" minOccurs="0" maxOccurs="1" />
<xs:element name="label" minOccurs="1" maxOccurs="1" />
<xs:element name="tracks" type="xs:decimal" minOccurs="0" maxOccurs="1" />
<xs:element name="playtime" type="xs:duration" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="Record" type="MediaType" />
</xs:schema>
Приведенная выше схема проверяет как:
<Record>
<Media>7in</Media>
<label>PlatinumDunce</label>
<!-- "4:33" is represented this way in xs:duration -->
<playtime>PT4M33S</playtime>
</Record>
, так и
<Record>
<Media>12in</Media>
<rpm>45</rpm>
<label>StarStruck</label>
<tracks>2</tracks>
</Record>
Изменить: Итак, я оставил одну вещь Что касается правила UPA: оно также учитывает порядок элементов. Один из быстрых способов обойти правило UPA - изменить порядок конфликтующих элементов Media
в одном из вложенных sequences
s. Это совершенно справедливо, например:
<xs:element name="Record">
<xs:complexType>
<xs:choice id="Media_Type" minOccurs="1" maxOccurs="1">
<xs:sequence>
<xs:element name="rpm" minOccurs="1" maxOccurs="1"/>
<xs:element name="Media" fixed="12in"/>
<xs:element name="label" minOccurs="1" maxOccurs="1"/>
<xs:element name="tracks" type="xs:decimal" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
<xs:sequence>
<xs:element name="Media" fixed="7in"/>
<xs:element name="label" minOccurs="1" maxOccurs="1"/>
<xs:element name="playtime" type="xs:duration" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
rpm
стоит перед Media
в первой последовательности, и это устраняет двусмысленность, но если rpm
должно идти после Media
(или Media
должен быть первым в обеих последовательностях), тогда действительно нет никакого способа обойти это.