Разработка веб-служб средствами Java. Ильдар ХабибуллинРазработкаWebслужбсредствами
Скачать 9.24 Mb.
|
Простой тип-объединение определяется компонентом в котором атрибутом memberTypes можно указать имена объединяемых типов. На- пример: Другой способ — записать в теле компонента определения простых типов, входящих в объединение. Например: name="size"> impleType> 32 Разработка Web-служб средствами Java value="8"/> value="72"/> value="small"/> value="medium"/> value="large"/> После этого атрибут size можно использовать, например, так: K/font> TeKCT Описание элементов и их атрибутов Элементы, которые будут применяться в документе XML, описываются в схеме компонентом элемента" элемента" число появлений элемента в документе" число появлений" /> Значение по умолчанию необязательных атрибутов minoccurs и равно 1. Это означает, что если эти атрибуты отсутствуют, то элемент дол- Глава 1. Обработка документов XML 33 жен появиться в документе XML ровно один раз. Определение типа элемен- та можно вынести в тело элемента пате="имя элемента" > Определение типа элемента Описание атрибута элемента тоже несложно: имя атрибута" атрибута" атрибута" по умолчанию" /> Необязательный атрибут use принимает три значения: • optional — описываемый атрибут необязателен (это значение по умол- чанию); • required — описываемый атрибут обязателен; prohibited — описываемый атрибут неприменим. Это значение полезно при определении подтипа, чтобы отменить некоторые атрибуты базового типа. Если описываемый атрибут необязателен, то атрибутом default можно за- дать его значение по умолчанию. Определение типа атрибута, — а это должен быть простой тип, — можно вынести в тело элемента пате="имя атрибута"> Тип атрибута Определение сложных типов Напомним, что тип элемента называется сложным, если в элемент вложены другие элементы и/или в открывающем теге элемента есть атрибуты. Сложный тип определяется компонентом имеющим вид: пате="имя типа" >Определение Необязательный атрибут name задает имя типа, а в теле компонента Определение сложного типа можно разделить на определение типа пустого элемента, элемента с простым телом, и элемента, содержащего вложенные элементы. Рассмотрим эти определения подробнее. 2 Зак. 748 34 Разработка Web-служб средствами Java Определение типа пустого элемента Проще всего определяется тип пустого элемента — элемента, не содержаще- го тела, а содержащего только атрибуты в открывающем теге. Таков, напри- мер, элемент листинга 1.2. Каждый атрибут описывается одним компонентом как в предыдущем разделе, например: />' После этого определения можно в схеме описать элемент типа type="imageType" /> а в документе XML использовать это описание: Определение типа элемента с простым телом Немного сложнее описание элемента, содержащего тело простого типа и атрибуты в открывающем теге. Этот тип отличается от простого типа только наличием атрибутов и определяется компонентом В теле этого компонента должен быть либо компонент В компоненте name="unit" /> name="precision" /> Эту конструкцию можно описать словами так: "Определяется тип элемента, тело которого содержит значения встроенного Глава 1. Обработка документов XML 35 простого типа Простой тип расширяется тем, что к нему до- бавляются атрибуты unit И precision". Если в схеме описать элемент этого типа следующим образом: name="result" /> то в документе XML можно написать base="xsd:decimal"> name="unit" /> /> Определение типа вложенных элементов Если значениями определяемого сложного типа будут элементы, содер- жащие вложенные элементы, как, например, элементы , листинга 1.2, то перед тем, как перечислять описания вло- женных элементов, надо выбрать модель группы (model group) вложенных элементов. Дело в том, что вложенные элементы, составляющие опреде- ляемый тип, могут появляться или в определенном порядке, или в про- извольном порядке, кроме того, можно выбирать только один из пере- численных элементов. Эта возможность и называется моделью группы элементов. Она определяется одним из трех компонентов Компонент Пусть, например, мы описываем книгу. Сначала определяем тип: Разработка Web-служб средствами Java name="author" type="xsd:normalizedString" /> type="xsd:normalizedstring" /> name="pages" /> /> Потом описываем элемент: name="book" type="bookType" /> Элементы И ДОЛЖНЫ входить в элемент именно в таком порядке. В документе XML надо писать: Ильф, Е. Если же вместо компонента и можно перечислять в любом порядке. Компонент Глава 1. Обработка документов XML 37 name="pages" /> type="xsd:normalizedString" /> Как видно из этого примера, компонент Кроме того, каждая группа в этих моделях может появиться сколько угодно раз, то есть, в компоненте Модель В компоненте не допускается применение компонентов Каждый элемент, входящий в группу модели Определение со сложным телом При определении сложного типа можно воспользоваться уже определен- ным, базовым, сложным типом, расширив его дополнительными элемента- ми, или, наоборот, удалив из него некоторые элементы. Для этого надо применить компонент В этом компоненте, так же как и в компоненте записывается либо компонент если надо расширить базовый тип, либо компонент Разработка Web-служб средствами Java Расширим, например, определенный выше тип Ьооктуре, добавив год изда- ния — элемент base="bookType"> name="year" type="xsd:gYear"> При сужении базового типа компонентом base="bookType"> name="author" type="xsd:normalizedString" /> Глава 1. Обработка документов XML 39 Это описание выглядит странно. Почему надо заново описывать все эле- менты, остающиеся после сужения? Не проще ли определить новый тип? Дело в том, что в язык XSD внесены элементы объектно-ориентированного программирования, которых мы не будем касаться. Расширенный и сужен- ный типы связаны со своим базовым типом отношением наследования, и к ним можно применить операцию подстановки. У всех типов языка XSD есть общий предок — базовый тип апуТуре. От него наследуются все слож- ные типы. Это подобно тому, как у всех классов Java есть общий предок — класс а все массивы наследуются от него. От базового типа апуТуре наследуется и тип — общий предок всех простых типов. Таким образом, сложные типы определяются как сужение типа апуТуре. Если строго подходить к определению сложного типа, то определение типа сделанное в начале предыдущего раздела, надо записать так: base="xsd:anyType"> name="author" type="xsd:normalizedString" /> type="xsd:normalizedString" /> Разработка Web-служб средствами Java Рекомендация языка XSD позволяет сократить эту запись, что мы и сделали в предыдущем разделе. Это подобно тому, как в Java мы опускаем слова "extends object" в заголовке описания класса. Закончим на этом описание языка XSD и перейдем к примерам. Пример: схема адресной книги В листинге 1.4 записана схема документа, приведенного в листинге 1.2. Листинг 1.4, Схема документа type="notebookType" /> name="notebookType"> name="person" type="personType" /> name="personType"> name="name"> name="first" use="optional" /> name="second" use="optional" /> name="surname" use="required" /> Глава 1. Обработка документов XML /> type="addressType" /> name="phone-list" type="phone-listType" /> /> name="city" type="cityType" /> name="zip" /> > name='type' /> name="placeType"> base = "xsd:string"> /> /> /> 42 Разработка Web-служб средствами Java name="phone-listType"> /> /> Листинг 1.4, как обычный документ XML, начинается с пролога, показы- вающего версию XML и определяющего стандартное пространство имен схемы XML с идентификатором Этому идентификатору дан префикс xsd." Конечно, префикс может быть другим, часто пишут префикс xs. Все описание схемы нашей адресной книжки заключено в одной третьей строке, в которой указано, что адресная книга состоит из одного элемента с именем notebook, имеющего сложный тип notebookType. Этот элемент должен появиться в документе ровно один раз. Остаток листинга 1.4 по- священ описанию типа этого элемента и других типов. Описание сложного типа notebookType несложно (простите за каламбур). Оно занимает три строки листинга, не считая открывающего и закрываю- щего тега, и просто говорит о том, что данный тип составляют несколько person personType. Описание типа personType немногим сложнее. Оно говорит, что этот тип составляют четыре name, birthday, address И phone-list. Для элемента name сразу же определены необязательные атрибуты f i r s t и Глава 1. Обработка документов XML second простого типа string, определенного в пространстве имен xsd. Тип обязательного атрибута surname — тоже string. Далее в листинге 1.4 определяются оставшиеся типы addressType, listType и ruDate. Необходимость определения простого типа ruDate воз- никает потому, что встроенный в схему XML тип date предписывает запи- сывать дату в виде 2003-02-22, а в России принят формат 22.02.2003. Тип ruDate определяется как сужение (restriction) типа string с помощью шаб- лона. Шаблон (pattern) для записи даты в виде задается регу- лярным выражением [8]. Безымянные типы Все описанные в листинге 1.4 типы используются только один раз. Поэтому необязательно давать типу имя. Схема XML, как говорилось выше, позволя- ет определять безымянные типы. Такое определение дается внутри описа- ния элемента. Именно так в листинге 1.4 описаны атрибуты элемента name. В листинге 1.5 показано упрощенное описание схемы адресной книги. Листинг_1.5._Схема_документа_XML_с_безымянными_типами____element_/>_/>___Разработка_Web-служб_средствами_Java'>Листинг 1.5. Схема документа XML с безымянными типами element /> /> Разработка Web-служб средствами Java /> name='city'> default='gorod' /> Глава 1. Обработка документов 45 /> /> Еще одно упрощение можно сделать, используя пространство имен по умолчанию. Посмотрим, какие пространства имен применяются в схемах XML. Пространства имен языка XSD Имена элементов и атрибутов, используемые при записи схем, определены в пространстве имен с идентификатором XMLSchema. Префикс имен, относящихся к этому пространству, часто называют или xsd, как в листингах 1.4 и 1.5. Каждый анализатор "зна- ет" это пространство имен и "понимает" имена из этого пространства. Можно сделать это пространство имен пространством по умолчанию, но тогда надо определить пространство имен для определяемых в схеме типов Разработка Web-служб средствами Java и элементов. Для удобства такого определения введено понятие целевого пространства имен (target namespace). Идентификатор целевого пространст- ва имен определяется атрибутом targetNamespace, например После такого определения имена, определяемые в этой схеме, будут относиться к новому пространству имен с идентификатором 2003/ntbNames. В листинге 1.6 вводится целевое пространство имен, а для уп- рощения записи листинга 1.5 стандартное пространство имен схемы XML с идентификатором сделано пространством имен по умолчанию. Имена, относящиеся к целевому пространству, снабжены префиксом ntb, чтобы они не попали в пространство имен по умолчанию. Листинг Схема с целевым пространством имен /> Глава 1. Обработка документов XML 47 /> /> raaxOccurs='unbounded'/> 48 Разработка Web-служб средствами Java Поскольку в листинге 1.6 пространством имен по умолчанию сделано про- странство префикс xsd не нужен. Следует заметить, что в целевое пространство имен попадают только гло- бальные имена, чьи описания непосредственно вложены в элемент Это естественно, потому что только глобальными именами можно восполь- зоваться далее в этой или другой схеме. В листинге 1.6 только одно гло- бальное имя Вложенные имена name, address и другие ассоциированы с глобальными именами. В схемах и документах XML часто применяется еще одно стандартное пространство имен. Рекомендация языка XSD определяет несколько атри- бутов: type, n i l , noNamespaceSchemaLocation, применяются не только в схемах, а и непосредственно в описываемых этими схемами документах XML, называемых экземплярами схем (XML schema instance). Имена этих атрибутов относятся к пространству имен Этому пространству имен чаще всего приписывают префикс xsi, например: Включение файлов схемы в другую схему В создаваемую схему можно включить файлы, содержащие другие схемы. Для этого есть два элемента схемы: и xsi:schemaLocation="names.xsd" /> Включаемый файл задается атрибутом xsi: schemaLocation. В примере использован для того, чтобы включить в создаваемую схему содержимое файла names.xsd. Файл должен содержать схему с описаниями и определе- ниями из того же пространства имен, что и в создаваемой схеме, или без пространства имен, то есть в нем не использован атрибут targetNamespace. Глава 1. Обработка документов XML 49 Это удобно, если мы хотим добавить к создаваемой схеме определения схе- мы names.xsd или просто хотим разбить большую схему на два файла. Мож- но представить себе результат включения так, как будто содержимое файла names.xsd просто записано на месте элемента Перед включением файла можно изменить некоторые определения, приве- денные в нем. Для этого используется элемент ine>, например: value="40"/> Если же включаемый файл содержит имена из другого пространства имен, то надо воспользоваться элементом схемы Например, пусть файл A.xsd начинается со следующих определений: а файл B.xsd начинается с определений Мы решили включить эти файлы в новый файл C.xsd. Это делается так: xsi:schemaLocation="A.xsd" /> /> Разработка Web-служб средствами Java После этого в файле C.xsd можно использовать имена, определенные в файлах A.xsd и B.xsd, снабжая их префиксами и соответственно. Элементы и следует располагать перед всеми определе- ниями схемы. Значение атрибута — строка URI, поэтому файл с включаемой схемой может располагаться в любом месте Интернета. Связь документа XML со своей схемой Программе-анализатору, проверяющей соответствие документа XML его схеме, надо как-то указать файлы (один или несколько), содержащие схему документа. Это можно сделать разными способами. Во-первых, можно по- дать эти файлы на вход анализатора. Так делает, например, проверяющий анализатор XSV (XML Schema Validator) $ xsv ntbl.xsd ntb2.xsd Во-вторых, можно задать файлы со схемой как свойство анализатора, уста- навливаемое методом setProperty или значение переменной окружения анализатора. Так делает, например, проверяющий анализатор Xerces. Эти способы удобны в тех случаях, когда документ в разных случаях нужно связать с разными схемами. Если же схема документа фиксирована, то ее удобнее указать прямо в документе XML. Это делается одним из двух спо- собов. Если элементы документа не принадлежат никакому пространству имен и записаны без префикса, то в корневом элементе документа записыва- ется атрибут указывающий расположение файла со схемой в форме URI: В этом случае в схеме не должно быть целевого пространства имен, то есть, атрибут 2. Если же элементы документа относятся к некоторому пространству имен, то применяется атрибут schemaLocation, в котором через пробел перечисляются пространства имен и расположение файла со схемой, описывающей это пространство имен. Продолжая пример предыдущего раздела, можно написать: |