При помощи 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! Элементы, вложенные в другие элементы, являются локальными элементами.