Замещение XML элементов

При помощи XML схем один элемент может замещать другой элемент.

Предположим, что есть пользователи из двух разных стран: Англии и Норвегии. Нам хотелось бы, чтобы у пользователя была возможность выбора, какие названия элементов использовать — норвежские или английские.

Чтобы решить эту задачу, нам необходимо в XML схеме определить декларацию substitutionGroup. Сначала декларируем головной элемент, а затем другие элементы, которые будут замечать головной элемент.


<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>

В приведенном выше примере элемент "name" является головным элементом, а элемент "navn" предназначен для замещения элемента "name".

Взгляните на следующий фрагмент XML схемы:


<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>

<xs:complexType name="custinfo">
   <xs:sequence>
      <xs:element ref="name"/>
   </xs:sequence>
</xs:complexType>

<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>

Валидный XML документ (в соответствии с приведенной выше схемой) мог бы выглядеть следующим образом:


<customer>
   <name>John Smith</name>
</customer>

или же так:


<kunde>
   <navn>John Smith</navn>
</kunde>

Блокирование замещения XML элементов

Чтобы закрыть какие-нибудь элементы от замещения определенными элементам, используется атрибут block:


<xs:element name="name" type="xs:string" block="substitution"/>

Посмотрите на следующий фрагмент XML схемы:


<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>

<xs:complexType name="custinfo">
   <xs:sequence>
      <xs:element ref="name"/>
   </xs:sequence>
</xs:complexType>

<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>

Валидный XML документ (в соответствии с приведенной выше схемой) выглядит следующим образом:


<customer>
   <name>John Smith</name>
</customer>

но следующий код больше не будет валидным:


<kunde>
   <navn>John Smith</navn>
</kunde>

Использование substitutionGroup

Тип замещающих элементов должен быть таким же (либо производным от него), как и у головного элемента. Если тип замещающего элемента такой же, как тип головного элемента, то вам не нужно указывать тип замещающего элемента.

Также следует знать, что все элементы в декларации substitutionGroup (и головной элемент, и замещающие элементы) должны быть декларированы как глобальные элементы. Иначе замещение не сработает!

Что такое глобальные элементы?

Глобальные элементы это такие элементы, которые являются непосредственными потомками элемента schema! Элементы, вложенные в другие элементы, являются локальными элементами.