Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)






Определение типа со сложным телом



 

При определении сложного типа можно воспользоваться уже определенным, базовым, сложным типом, расширив его дополнительными элементами, или, наоборот, удалив из него некоторые элементы. Для этого необходимо применить компонент complexContent. В этом компоненте, так же как и в компоненте simpleContent, записывается либо компонент extension, если надо расширить базовый тип, либо компонент restriction, если нужно его сузить. Базовый тип указывается атрибутом base, так же как и при записи компонента simpleContent, но теперь это должен быть сложный, а не простой тип.

Расширим, например, определенный выше тип bookType, добавив год издания — элемент year:

 

<xsd:complexType name="newBookType">

<xsd:complexContent>

<xsd:extension base="bookType">

<xsd:sequence>

<xsd:element name="year" type="xsd:gYear">

</xsd:sequence>

</xsd:extension>

</xsd:complexContent>

</xsd:complexType>

 

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

 

<xsd:complexType name="newBookType">

<xsd:complexContent>

<xsd:restriction base="bookType">

<xsd:sequence>

<xsd:element name="author" type="xsd:normalizedString" minOccurs="0" />

<xsd:element name="title" type="xsd:normalizedString" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

 

Это описание выглядит странно. Почему надо заново объявлять все элементы, остающиеся после сужения? Не проще ли определить новый тип? Дело в том, что в язык XSD внесены элементы объектно-ориентированного программирования, которых мы не будем касаться. Расширенный и суженный типы связаны со своим базовым типом отношением наследования, и к ним можно применить операцию подстановки. У всех типов языка XSD есть общий предок — базовый тип anytype. От него наследуются все сложные типы. Это подобно тому, как у всех классов Java есть общий предок — класс object, а все массивы наследуются от него. От базового типа апутуре наследуется и тип anySimpleType — общий предок всех простых типов.

Таким образом, сложные типы определяются как сужение типа апутуре. Если строго подходить к определению сложного типа, то определение типа bookType, сделанное в начале предыдущего раздела, надо записать так:



 

<xsd:complexType name="bookType">

<xsd:complexContent>

<xsd:restriction base="xsd:anyType">

<xsd:sequence maxOccurs="unbounded">

<xsd:element name="author" type="xsd:normalizedString" minOccurs="0" />

<xsd:element name="title" type="xsd:normalizedString" />

<xsd:element name="pages" type="xsd:positiveInteger" minOccurs="0" />

<xsd:element name="publisher" type="xsd:normalizedString"minOccurs="0" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

 

Ниже в листинге 1.45 представлена XSD-схема для XML-документа из листинга 1.44.

 

<?xml version="1.0"?>

<notebook>

<person>

<name first="Иван" second="Петрович" surname="Сидоров" />

<birthday>25.03.1977</birthday>

<adress>

<street>Садовая, 23-15</street>

<city>Урюпинск</city>

<zip>123456</zip>

</adress>

<phone-list>

<work-phone>2654321</work-phone>

<work-phone>2654023</work-phone>

<home-phone>3456781</home-phone>

</phone-list>

</person>

<person>

<name first="Мария" second="Петровна" surname="Сидорова" />

<birthday>17.035.1969</birthday>

<adress>

<street>Ягодная, 17</street>



<city>Жмеринка</city>

<zip>234561</zip>

</adress>

<phone-list>

<work-phone></work-phone>

<work-phone></work-phone>

<home-phone>2334455</home-phone>

</phone-list>

</person>

</notebook>

Листинг 1.44

 

<?xml version="1.0"?>

<!-- Имя файла: AdressBook01.xsd -->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="notebook" type="notebookType" />

<xsd:complexType name="notebookType">

<xsd:element name="person" type="personType" minOccurs="0" maxOccurs="unbounded" />

</xsd:complexType>

<xsd:complexType name="personType">

<xsd:sequence>

<xsd:element name="name">

<xsd:complexType>

<xsd:attribute name="first" type="xsd:string"

use="optional" />

<xsd:attribute name="second" type="xsd:string"

use="optional" />

<xsd:attribute name="surname" type="xsd:string"

use="required" />

</xsd:complexType>

</xsd:element>

<xsd:element name="birthday" type="ruDate" minOccurs="0" />

<xsd:element name="address" type="addressType"

minOccurs="0" maxOccurs="unbounded" />

<xsd:element name="phone-list" type="phone-listType"

minOccurs="0" />

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name="addressType" >

<xsd:sequence>

<xsd:element name="street" type="xsd:string" />

<xsd:element name="city" type="cityType" />

<xsd:element name="zip" type="xsd:positiveInteger" />

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name='cityType'>

<xsd:simpleContent>

<xsd:extension base='xsd:string' >

<xsd: attribute name='type' type='placeType'

default='город' />

</xsd:extension>

</xsd:simpleContent>

</xsd:complexType>

<xsd:simpleType name="placeType">

<xsd:restriction base = "xsd:string">

<xsd:enumeration value="ropoд" />

<xsd:enumeration value="пoceлoк" />

<xsd:enumeration value="дepeвня" />

</xsd:restriction>

</xsd:simpleType>

<xsd:complexType name="phone-listType">

<xsd:element name="work-phone" type="xsd:string"

minOccurs="0" maxOccurs="unbounded" />

<xsd:element name="home-phone" type="xsd:string"

minOccurs="0" maxOccurs="unbounded" />

</xsd:complexType>

<xsd:simpleType name="ruDate">

<xsd:restriction base="xsd:string">

<xsd:pattern value="[0-9]{2}.[0-9]{2}.[0-9]{4}" />

</xsd:restriction>

</xsd:simpleType>

</xsd:schema>

Листинг 1.45

 

Листинг 1.45, как обычный XML-документ, начинается с пролога, показывающего версию XML и определяющего стандартное пространство имен схемы XML с идентификатором http://www.w3.org/2001/XMLSchema. С этим идентификатором связан префикс xsd. Конечно, префикс может быть другие, часто пишут префикс xs.

Все описание схемы нашей адресной книжки заключено в третьей строке, в которой указано, что адресная книга состоит из одного элемента с именем notebook, имеющего сложный тип notebookType. Этот элемент должен появиться в документе ровно один раз. Остальная часть листинга 1.45 посвящена описанию типа этого элемента и других типов.

Определение сложного типа notebookType несложно. Оно занимает три строки листинга, не считая открывающего и закрывающего тега, и просто говорит о том, что данный тип составляют несколько элементов person типа personType.

Определение типа personType немногим сложнее. Оно означает, что этот тип составляют четыре элемента: name, birthday, address и phone-list. Для элемента name сразу же объявлены необязательные атрибуты first и second простого типа string, определенного в пространстве имен xsd. Тип обязательного атрибута surname — тоже string.

Далее в листинге 1.45 определяются оставшиеся типы addressType, phonelistType и ruDate. Необходимость определения простого типа ruDate возникает потому, что встроенный в схему XML тип date предписывает записывать дату в виде 2003-02-22, а у нас принят формат 22.02.2003. Тип ruDate определяется как сужение (restriction) типа string с помощью шаблона. Шаблон (pattern) для записи даты в виде ДД.ММ.ГГГГ задается регулярным выражением.

 

Безымянные типы

 

Все описанные в листинге 1.45 типы используются только один раз. Поэтому необязательно давать типу имя. Схема XML, как говорилось выше, позволяет определять безымянные типы. Такое определение дается внутри описания элемента. Именно так в листинге 1.45 описаны атрибуты элемента name. В листинге 1.46 показано упрощенное описание схемы адресной книги.

 

<?xml version="1.0"?>

<!-- Имя файла: AdressBook02.xsd -->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="notebook">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="person" type="personType" maxOсcurs="unbounded" />

<xsd:complexType>

<xsd:sequence>

<xsd:element name="name">

<xsd:complexType>

<xsd:attribute name="first" type="xsd:string"

use="optional" />

<xsd:attribute name="second" type="xsd:string"

use="optional" />

<xsd:attribute name="surname" type="xsd:string"

use="required" />

</xsd:complexType>

</xsd:element>

<xsd:element name="birthday">

<xsd:simpleType>

<xsd restriction base="xsd:string">

<xsd:pattern value="[0-9]{2}.[0-9]{2}.[0-9]{4}">

</xsd restriction>

</xsd:simpleType>

</xsd:element>

<xsd:element name="address" maxOccurs="unbounded">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="street" type="xsd:string" />

<xsd:element name="city">

<xsd:complexType>

<xsd:simpleContent>

<xsd:extension base='xsd:string' >

<xsd: attribute name='type' type='xsd:string'

use='optional' default='город' />

</xsd:extension>

</xsd:simpleContent>

</xsd:complexType>

</xsd:element>

<xsd:element name="zip" type="xsd:positiveInteger" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd: element name="phone-listType">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="work-phone" type="xsd:string"

minOccurs="0" maxOccurs="unbounded" />

<xsd:element name="home-phone" type="xsd:string"

minOccurs="0" maxOccurs="unbounded" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

Листинг 1.46

 

Еще одно упрощение можно сделать, используя пространство имен по умолчанию.

 

9.7. Пространства имён языка XSD

 

Имена элементов и атрибутов, используемые при записи схем, определены в пространстве имен с идентификатором http://www.w3.org/2001/XMLSchema. Префикс имен, относящихся к этому пространству, часто называют xs или xsd, как в листингах 1.45 и 1.46. Каждый анализатор "знает" это пространство имен и "понимает" имена из этого пространства.

Можно сделать это пространство имен пространством по умолчанию, но тогда надо задать пространство имен для определяемых в схеме типов и элементов. Для удобства такого определения введено понятие целевого пространства имен(target namespace). Идентификатор целевого пространства имен определяется атрибутом targetNamespace, например:

 

<xsd:schema targetNamespace="http://some.firm.com/2003/ntbNames">

 

После такого определения имена, определяемые в этой схеме, будут относиться к новому пространству имен с идентификатором http://some.firm.com /2003/ntbNames. Так сделано в листинге 1.47. Для упрощения записи в нем стандартное пространство имен схемы XML с идентификатором http://www.w3.org/2001/XMLSchema сделано пространством имен по умолчанию. Имена, относящиеся к целевому пространству, снабжены префиксом ntb, чтобы они не попали в пространство имен по умолчанию.

 

<?xml version="1.0"?>

<!-- Имя файла: AdressBook03.xsd -->

<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"

targetNamespace="http://some.firm.com/2003/ntbNames"

xmlns:ntb="http://some.firm.com/2003/ntbNames"

<element name="ntb:notebook">

<complexType>

<sequence>

<xsd:element name="person" maxOсcurs="unbounded" />

<complexType>

<sequence>

<element name="name">

<complexType>

<attribute name="first" type="string"

use="optional" />

<attribute name="second" type="string"

use="optional" />

<attribute name="surname" type="string"

use="required" />

</complexType>

</element>

<element name="birthday">

<simpleType>

<restriction base="string">

<pattern value="[0-9]{2}.[0-9]{2}.[0-9]{4}">

</restriction>

</simpleType>

</element>

<element name="address" maxOccurs="unbounded">

<complexType>

<sequence>

<element name="street" type="string" />

<element name="city" type="string" />

<element name="zip" type="positiveInteger" />

</sequence>

</complexType>

</element>

 

<element name="phone-listType">

<complexType>

<sequence>

<element name="work-phone" type="string"

minOccurs="0" maxOccurs="unbounded" />

<element name="home-phone" type="string"

minOccurs="0" maxOccurs="unbounded" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

Листинг 1.47

 

Поскольку в листинге 1.47 пространством имен по умолчанию сделано пространство http://www.w3.org/2001/XMLSchema, префикс xsd не нужен. Следует заметить, что в целевое пространство имен попадают только глобальные имена, чьи описания непосредственно вложены в корневой элемент schema. Это естественно, потому что только глобальными именами можно воспользоваться далее в этой или другой схеме. В листинге 1.47 лишь одно глобальное имя notebook. Вложенные имена name, address и др. только ассоциированы с глобальными именами.

В схемах и документах XML часто применяется еще одно стандартное пространство имен. Рекомендация языка XSD определяет несколько атрибутов: type, nil, schemaLocation, noNamespaceSchemaLocation, которые применяются не только в схемах, а и непосредственно в описываемых этими схемами документах XML, называемых экземплярами схем (XML schema instance). Имена этих атрибутов относятся к пространству имен http://www.w3.org/2001/XMLSchema-instance. Этому пространству имен чаще всего приписывают префикс xsi, например:

 

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

 


Эта страница нарушает авторские права

allrefrs.ru - 2019 год. Все права принадлежат их авторам!