4.5 Переопределение типов и групп

В Разделе 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, как показано в следующем фрагменте:

Фрагмент из ipo.xml, использующий переопределенный адрес

....
<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 не защищает Вас от таких ошибок, и он должен использоваться осторожно.

 

Сайт создан в системе uCoz