В продолжение первой статьи о простых типах (SimpleTypes) добавлю следующее.
Очень часто на простых типах используют ограничения — restriction. Т.е. определенные фильтры на данные, которые вы будете использовать. Пример:
<xs:element name="number">
<xs:simleType>
<xs:restriction base:"xs:integer"> <!-- фильтр -->
<xs:maxInclusive value="40"/> <!-- max включение -->
<xs:minExlclusive value="3"/> <!-- min включение -->
</xs:restriction>
</xs:simleType>
</xs:element>
В примере мы создали элемент number, он простого типа. Создадим ограничение на число: 3 — 40.
Еще один пример с применением фильтра, но идет перечисление дней недели:
<xs:element name="workDays">
<xs:simleType>
<xs:restriction base:"xs:string"> <!-- фильтр -->
<xs:enumeration value="Понедельник"/> <!-- начало перечисления -->
<xs:enumeration value="Вторник"/>
<xs:enumeration value="Среда"/>
<xs:enumeration value="Четверг"/>
<xs:enumeration value="Пятница"/>
<xs:enumeration value="Суббота"/>
<xs:enumeration value="Воскресенье"/>
</xs:restriction>
</xs:simleType>
</xs:element>
В этом примере применили фильтр на дни недели, т.е. допустимы только названия дней недели в качестве значений. Если я напишу ‘как дела?’, обработчик выдаст ошибку.
Часто такие фильтры ставятся на какие-то перечисляемые типы (например, перечисление даты).
Теперь перейдем к сложным типам. В сложные типы (ComplexType) можно поместить внутрь несколько типов, а в простые типы (SimpleType) — ничего, кроме значений не поместить.
Содержание статьи
Сложные типы данных
Рассмотрим пример:
<xsd:comlexType name="FruitType">
<xsd:sequence>
<xsd:element name="nameFruit" type="xsd:string"/>
<xsd:element name="priceFruit" type="xsd:int"/>
</xsd:sequence>
</sxd:complexType>
Такие типы данных можно создавать самому, какие хочешь. В 1-й строке мы создали сложный тип данных FruitType. Этот тип содержит внутри себя 2 элемента с разными типами данных — строка (название фрукта) и число (цена фрукта), поэтому он комплексного типа (complexType).
Повторения элементов
Часто нужно, чтобы элементы повторялись. И чтобы в xml документе не дублировать эти элементы, придумали следующее (если помните, в DTD для этого применяли модификаторы — * и +). Опять вернемся к фруктам:
<xsd:comlexType name="FruitType">
<xsd:sequence>
<xsd:element name="nameFruit" type="xsd:string"
minOccurs="0" <!-- минимум -->
maxOccurs="unbounded"/> <!-- максимум -->
<xsd:element name="priceFruit" type="xsd:int"/>
</xsd:sequence>
</sxd:complexType>
Здесь появляются 2 атрибута — минимальное количество (minOccurs) и максимальное количество (maxOccurs). Допускается использовать значение от нуля до unbounded (неограничено).
Определение атрибутов
Атрибут является частью типа. Если нужно добавить атрибут, применим элемент attribute, у которого 3 обязательных атрибута:
<xsd:attribute name="phone"
type="xsd:string"
use="optional"/> <!-- необязательно -->
Важно! Атрибут не входит в элемент sequence! Туда входит только то, что внутри нашего элемента. Поэтому атрибуты обычно пишутся после композитора sequence.
Группы элементов
Мы просто создаем группу, а потом ссылаемся на нее в другом элементе.
<xs:sequence>
<xs:group ref="FruitGroup"/> //ссылка на группу
<xs:element name="color" type="xs:string" /> <!-- еще один элемент -->
</xs:sequence>
Т.е. группу используют, чтобы описать общее у разных типов.
Расширения типов
Т.е. это создание одного типа на основе другого. Рассмотрим на примере:
<!-- один тип данных -->
<xsd:complexType name="acct">
<xsd:sequence>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="number" type="xsd:string"/>
<xsd:element name="type" type="acctTypeCode"/>
<xsd:element name="balance" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="status" type="xsd:string"/>
</xsd:complexType>
<!-- второй тип данных -->
<xsd:complexType name="savingAcct">
<xsd:complexContent>
<xsd:extension base="acct"> <!-- расширяю тип аккаунта -->
<xsd:sequence>
<xsd:element name="minimalBalance" type="xsd:decimal"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
У нас есть комплексный тип аккаунт (acct) — банковский счет. Он состоит из набора элементов: description (описание счета), number (номер счета), type (тип счета) и balance (баланс счета), есть также атрибут status. В итоге у нас получился один тип данных. Это не элемент! Чтобы элемент появился, надо сделать element type=”acct”.
И второй тип данных — депозитный счет. Это то же самое, что и банковский счет, но у него появляются дополнительные свойства. Например, минимальный баланс, при котором действует высокая процентная ставка (minimalBalance). Остальное, все как у обычного счета.
Вначале я делаю новый тип — savingAcct (депозитный счет). Он комплексного типа. Расширяю тип аккаунта последовательностью элементов (minimalBalance). Т.е. в новый тип попадает все, что есть у верхнего, плюс новый элемент баланса.