(Это был бы дополнительный комментарий в ответе @hugh jadick, но он был слишком длинным для такого.)
У вас есть две проблемы в вашем первоначальном дизайне, которые усложняют структуру:
- у вас есть что-то, что можно рассматривать как ограничение совместного вхождения, потому что
<subType>
может появляться только тогда, когда присутствует <mainType>
- объявления элементов несовместимы, поскольку у вас есть
- ...в том же контексте (дочерние элементы
<type>
) - ... элементов с одинаковыми именами (
<mainType>
) - ... но с другим типом (другое значение и связанные
<subType>
элементы).
В XML Schema 1.0 не существует общего метода, позволяющего реализовать эти функции, хотя они могут быть достигнуты в некоторых случаях и / или с помощью некоторых методов.Одним из возможных способов решения проблемы неоднозначного типа является использование атрибута xsi:type
в документе экземпляра для определения используемого типа схемы (пример 1).
Вместо того, чтобы использовать некоторые возможные обходные пути для решения этих проблем, я предлагаю вам следовать @ 1027 * answer @hugh jadick и создавать элементы с разными именами для всех основных типов, которые также будут иметь разные элементы дляразные подтипы.Если вам не нравится иметь имя типа в качестве имени элемента (или оно недопустимо для имени элемента XML), вы можете поместить его в атрибут, возможно, используя значение по умолчанию или фиксированное значение (<myType1 typeName="Type 1 name">
) (Пример 2).Если подтипы являются взаимоисключающими, вы также можете поместить их в атрибут (<myType1 subType="subType2">
).Если вы действительно хотите иметь имя типа в содержимом элемента (<mainType1>Type 1 name</mainType1>
), то, вероятно, лучше иметь элементы <subType>
в качестве следующих братьев и сестер, а не потомков <mainType1>
, потому что это приведет к смешанному содержимому, которое легковызывает проблемы, связанные с пробелами и позицией текстового узла (пример 3).
Да, группы подстановки также могут использоваться с ответом @hugh jadick.У вас будет абстрактный элемент <mainType>
, и все определения элементов основного типа будут иметь атрибут substitutionGroup="mainType"
.Вы по-прежнему должны иметь разные имена для разных элементов основного типа, потому что они допускают различный набор разрешенных элементов / значений.Тип этих элементов должен быть получен из типа абстрактного <mainType>
элемента, который они заменяют (Пример 4).
Примеры кода
Пример 1
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:element name="mainType" type="mainType1"/>
<xs:element name="mainType" type="mainType2"/>
<xs:element name="mainType" type="mainType3"/>
</xs:choice>
</xs:complexType>
</xs:element>
<type>
<mainType xsi:type="mainType1"/>
</type>
Пример 2
<xs:element name="mainType1">
<xs:complexType>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
<xs:attribute name="typeName" type="xs:string"/>
</xs:complexType>
</xs:element>
Пример 3
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="mainType" type="mainType1"/>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
</xs:sequence>
<!-- repeat similarily for other main types -->
<xs:sequence>
<!-- ... -->
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
Пример 4
<xs:element name="type">
<xs:complexType>
<xs:sequence>
<xs:element ref="mainType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="mainType" type="mainType" abstract="true"/>
<xs:element name="mainType1" type="typeForMainType1" substitutionGroup="mainType"/>
<xs:element name="mainType2" type="typeForMainType2" substitutionGroup="mainType"/>
<xs:complexType name="mainType">
<!-- definition for mainType -->
</xs:complexType>
<xs:complexType name="typeForMainType1">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="typeForMainType2">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>