В Разделе 4.1 мы
описали, как включить определения и объявления, получаемые из файлов внешних
схем, которые имеют то же самое целевое пространство имен. Механизм include
дает возможность Вам использовать внешне
созданные компоненты схем "как есть", то есть без
какой-либо модификации. Мы только что описали, как получать новые типы посредством
расширения и ограничения. Здесь мы опишем механизм redefine
, который позволит Вам переопределить
простые и сложные типы, группы, и группы атрибутов, которые получены из файлов внешних
схем. Подобно механизму include
, redefine
требует, чтобы внешние компоненты
находились в том же самом целевом пространстве имен, что и переопределяемая
схема, хотя внешние компоненты из схем, которые не имеют пространства имен
также могут быть переопределены. В последних случаях, переопределенные
компоненты становятся частью целевого пространства имен переопределенной схемы.
Для иллюстрации механизма redefine
, мы используем его вместо механизма include
в международном счете на покупку, ipo.xsd
, и изменим определение сложного типа Address
, который содержится в address.xsd
:
<schema targetNamespace=”http://www.example.com/IPO” xmlns=”http://www.w3.org/2001/XMLSchema” xmlns:ipo=”http://www.example.com/IPO”> <!-- bring in address constructs --> <redefine schemaLocation=”http://www.example.com/schemas/address.xsd”> <!-- redefinition of Address --> <complexType name=”Address”> <complexContent> <extension base=”ipo:Address”> <sequence> <element name=”country” type=”string”/> </sequence> </extension> </complexContent> </complexType> </redefine> <!-- etc --> </schema>
Элемент redefine
действует подобно элементу include
, поскольку он включает все объявления и
определения из файла address.xsd
. Определение сложного типа Address
использует подобный синтаксис расширения,
чтобы добавить элемент country
к определению Address
. Однако обратите внимание, что исходный тип тоже Address.
Вне
элемента redefine
любая такая попытка определить сложный
тип с тем же самым именем (и в том же самом пространстве имен), как и исходный,
из которого он произошел, вызвала бы ошибку. Но в данном случае ошибки нет, и
расширенное определение Address
становится единственным определением Address
.
Теперь, когда Address
переопределен, расширение применяется ко
всем компонентам схемы, которые используют Address
. Например, address.xsd
содержит
определения международных типов адреса,
которые получены из Address
. Этот вывод отражен в переопределенном типе Address
, как показано в следующем фрагменте:
.... <shipTo exportCode=”1” xsi:type=”ipo:UKAddress”> <name>Helen Zoe</name> <street>47 Eden Street</street> <city>Cambridge</city> <!-- country was added to Address which is base type of UKAddress --> <country>United Kingdom</country> <!-- postcode was added as part of UKAddress --> <postcode>CB1 1JR</postcode> </shipTo> ....
Наш
пример был тщательно построен таким образом, чтобы переопределенный тип
Address
ни каким образом не конфликтовал с типами, которые получены из
оригинального определения Address
. Однако отметим, что конфликт мог бы возникнуть очень просто.
Например, если при образовании международного типа адреса в расширенный Address
был бы добавлен элемент
country
, то тогда переопределение Address
должно было бы добавить элемент с тем же
самым именем к модели содержания Address
. Неправильно иметь два элемента с одним
и тем же именем (и в одном и том же целевом пространстве имен), но разными
типами в модели содержания. Поэтому попытка переопределить Address
вызвала бы ошибку. Вообще, redefine
не защищает Вас от таких ошибок, и он
должен использоваться осторожно.