Главная      Учебники - Разные     Лекции (разные) - часть 15

 

Поиск            

 

на тему: Язык xml. Язык запросов X query

 

             

на тему: Язык xml. Язык запросов X query

Министерство образования Республики Беларусь

Белорусский Государственный Университет

Экономический факультет

Кафедра экономической информатики и математической экономики

на тему:

Язык XML. Язык запросов X - Query .

Выполнили:

студентки 1 курса

отделения "Менеджмент"

Герасимова Серафима Валерьевна

Бизунова Вера Владимировна

Научный руководитель

Кожич П.П.

Минск 2007

Содержание

Содержание. 2

Введение. 5

Возникновение языка XML и его задачи. 7

Версии XML. 8

Достоинства. 8

Недостатки. 10

Язык SGML. 11

XML-генераторы. 12

DTD-определения. 13

Объектная модель документа (DOM) 14

Создание XML-документа. 17

Правила создания. 18

Структура документа. 19

Конструкции языка. 20

Элементы данных. 20

Комментарии. 22

Атрибуты. 23

Специальные символы. 23

Директивы анализатора. 24

CDATA.. 24

Определение типа документа(DTD) 25

Определение элемента. 26

Пример корректного XML- документа: 27

Определение атрибутов. 28

Типизация данных. 29

Схемы данных. 32

Внешний вид схем данных. 32

Область схемы данных. 33

Описание элементов. 34

Атрибуты элемента. 34

Модель содержимого элемента. 35

Иерархия классов. 38

Ограничения на значения. 38

Использование правил из внешних схем. 38

Типы данных. 39

Язык запросов XQuery. 42

Модель данных. 43

Иллюстрация запросной модели. 45

Выражения XQuery. 47

Основы. 47

Выражения пути. 48

Предикаты. 50

Конструкторы элементов. 53

Итерация и сортировка. 55

Арифметические операции. 58

Операции над последовательностями. 60

Условные выражения. 62

Кванторные выражения. 62

Функции. 63

Типы. 66

Проверка корректности. 67

Структура запроса. 67

Итоги. 68

XPath. 69

Основные элементы путей адресации. 69

Анализ выражения. 71

Оси. 72

Системные функции. 73

Функции с множествами. 74

Строковые функции. 75

Логические функции. 75

Числовые функции. 76

Способы просмотра XML-документов. 77

Отображение XML во Всемирной паутине. 78

Стилевые таблицы XSL. 79

Словари XML. 80

Приложение. 82

Пример XML-документа. 82

DTD-определение для XML-документа. 84

Заключение. 86

Список литературы. 88

Предметный указатель. 90

Для заметок. 92

Введение

XML (Extensible Markup Language) - это новый SGML-производный язык разметки документов, позволяющий структурировать информацию разного типа, используя для этого произвольный набор инструкций.

XML предназначен для хранения структурированных данных (взамен существующих файлов баз данных), для обмена информацией между программами, а также для создания на его основе более специализированных языков разметки (например, XHTML), иногда называемых словарями. XML является упрощённым подмножеством языка SGML.

XML - это язык разметки, описывающий целый класс объектов данных, называемых XML- документами. Этот язык используется в качестве средства для описания грамматики других языков и контроля за правильностью составления документов.

Спецификация XML была предложена консорциумом W3C (организацией по стандартизации новых Web-технологий) в качестве рекомендации, утверждена в 1998 году.

Сегодня XML может использоваться в любых приложениях, которым нужна структурированная информация - от сложных геоинформационных систем, с гигантскими объемами передаваемой информации до обычных "однокомпьютерных" программ, использующих этот язык для описания служебной информации. Можно выделить множество задач, связанных с созданием и обработкой структурированной информации, для решения которых может использоваться XML:

• В первую очередь, эта технология может оказаться полезной для разработчиков сложных информационных систем, с большим количеством приложений, связанных потоками информации самой различной структурой. В этом случае XML - документы выполняют роль универсального формата для обмена информацией между отдельными компонентами большой программы.

• XML является базовым стандартом для нового языка описания ресурсов, RDF, позволяющего упростить многие проблемы в Web, связанные с поиском нужной информации, обеспечением контроля за содержимым сетевых ресурсов, создания электронных библиотек и т.д.

• Язык XML позволяет описывать данные произвольного типа и используется для представления специализированной информации, например химических, математических, физических формул, медицинских рецептов, нотных записей, и т.д. Это означает, что XML может служить мощным дополнением к HTML для распространения в Web "нестандартной" информации. Возможно, в самом ближайшем будущем XML полностью заменит собой HTML, по крайней мере, первые попытки интеграции этих двух языков уже делаются (спецификация XHTML).

• XML-документы могут использоваться в качестве промежуточного формата данных в трехзвенных системах. Обычно схема взаимодействия между серверами приложений и баз данных зависит от конкретной СУБД и диалекта SQL, используемого для доступа к данным. Если же результаты запроса будут представлены в некотором универсальном текстовом формате, то звено СУБД, как таковое, станет "прозрачным" для приложения. Кроме того, сегодня на рассмотрение W3C предложена спецификация нового языка запросов к базам данных XQL, который в будущем может стать альтернативой SQL.

• Информация, содержащаяся в XML-документах, может изменяться, передаваться на машину клиента и обновляться по частям. Разрабатываемые спецификации XLink и Xpointer позволят ссылаться на отдельные элементы документа c учетом их вложенности и значений атрибутов.

• Использование стилевых таблиц (XSL) позволяет обеспечить независимое от конкретного устройства вывода отображение XML- документов.

• XML может использоваться в обычных приложениях для хранения и обработки структурированных данных в едином формате.

XML-документ представляет собой обычный текстовый файл, в котором при помощи специальных маркеров создаются элементы данных, последовательность и вложенность которых определяет структуру документа и его содержание. Основным достоинством XML документов является то, что при относительно простом способе создания и обработки (обычный текст может редактироваться любым тестовым процессором и обрабатываться стандартными XML анализаторами), они позволяют создавать структурированную информацию, которую хорошо "понимают" компьютеры.

XML позволяет описывать и передавать такие структурированные данные, как:

• отдельные документы;

• метаданные, описывающие содержимое какого-либо узла Internet ;

• объекты, содержащие данные и методы работы с ними (например, элементы управления ActiveX или объекты Java);

• отдельные записи (например, результаты выполнения запросов к базам данных);

• всевозможные Web-ссылки на информационные и людские ресурсы Internet (адреса электронной почты, гипертекстовые ссылки и пр.).

Возникновение языка XML и его задачи

Язык XML был разработан группой XML Working Group (первоначально называемой SGML Editorial Review Board), сформированной в 1996 году под патронажем World Wide Web Consortium (W3C). Председательствовал в группе Jon Bosak из Sun Microsystems, принимавший также активное участие в работе группы XML Special Interest Group (ранее известной как SGML Working Group), которая тоже была сформирована W3C. Связь группы с W3C обеспечивает Dan Connolly.

При разработке языка XML ставились следующие задачи:

1. XML должен быть пригоден для непосредственного использования в Интернет.

2. XML должен иметь широкий круг применения.

3. XML должен быть совместим с SGML.

4. Обработчики документов XML должны быть просты в написании.

5. Количество факультативных свойств в XML должно быть сведено к абсолютному минимуму, в идеале число их вообще должно быть нулевым.

6. XML документы должны быть удобны для чтения и достаточно понятны.

7. Подготовка XML документа должна осуществляться быстро.

8. Процедура построения XML документа должна быть формальной и точной.

9. Процедура создания XML документов должна быть проста.

10. Краткость при разметке XML документа имеет минимальное значение.

Данная спецификация в сочетании с остальными связанными с нею стандартами (Unicode и ISO/IEC 10646 для символов, Internet RFC 1766 для тэгов идентификации языка, ISO 639 для кодов с названием языка и ISO 3166 для кодов с названием страны) дает всю необходимую информацию для понимания языка XML (версия 1.0) и создания компьютерных программ для его обработки.

Версии XML

• XML 1.0

• XML 1.1

Достоинства

• XML (человеко-ориентированный) — это формат, одновременно понятный и человеку и компьютеру.

• XML поддерживает Юникод.

• В формате XML могут быть описаны основные структуры данных — такие как записи, списки и деревья.

• XML — это самодокументируемый формат, который описывает структуру и имена полей также как и значения полей.

• XML имеет строго определённый синтаксис и требования к парсингу, что позволяет ему оставаться простым, эффективным и непротиворечивым.

• XML также широко используется для хранения и обработки документов как он-лайн, так и офф-лайн.

• XML — формат, основанный на международных стандартах.

• Иерархическая структура XML подходит для описания практически любых типов документов.

• XML представляет собой простой текст, свободный от лицензирования и каких-либо ограничений.

• XML не зависит от платформы.

• XML является подмножеством SGML (который используется с 1986 года). Уже накоплен большой опыт работы с языком и созданы специализированные приложения.

• XML не накладывает требований на расположение символов на строке.

Одним из очевидных достоинств XML является возможность использования его в качестве универсального языка запросов к хранилищам информации. Сегодня в глубинах W3C находится на рассмотрении рабочий вариант стандарта XML-QL(или XQL), который, возможно, в будущем составит серьезную конкуренцию SQL. Кроме того, XML-документы могут выступать в качестве уникального способа хранения данных, который включает в себя одновременно средства для разбора информации и представления ее на стороне клиента. В этой области одним из перспективных направлений является интеграция Java и XML - технологий, позволяющая использовать мощь обеих технологий при построении машинно-независимых приложений, использующих, кроме того, универсальный формат данных при обмене информации.

XML позволяет также осуществлять контроль за корректностью данных, хранящихся в документах, производить проверки иерархических соотношений внутри документа и устанавливать единый стандарт на структуру документов, содержимым которых могут быть самые различные данные. Это означает, что его можно использовать при построении сложных информационных систем, в которых очень важным является вопрос обмена информацией между различными приложениями, работающими в одной системе. Создавая структуру механизма обмена информации в самом начале работы над проектом, менеджер может избавить себя в будущем от многих проблем, связанных с несовместимостью используемых различными компонентами системы форматов данных.

Недостатки

· Синтаксис XML избыточен.

o Размер XML документа существенно больше бинарного представления тех же данных. В грубых оценках величину этого фактора принимают за 1 порядок (в 10 раз).

o Размер XML документа существенно больше, чем документа в альтернативных текстовых форматах передачи данных (например JSON) и особенно в форматах данных оптимизированных для конкретного случая использования.

o Избыточность XML может повлиять на эффективность приложения. Возрастает стоимость хранения, обработки и передачи данных.

o Для большого количества задач не нужна вся мощь синтаксиса XML и можно использовать значительно более простые и производительные решения.

· XML не содержит встроенной в язык поддержки типов данных. В нём нет понятий «целых чисел», «строк», «дат», «булевых значений» и т.д.

· Иерархическая модель данных, предлагаемая XML, ограничена по сравнению с реляционной моделью и объектно-ориентированными графами.

· Пространства имён XML сложно использовать и их сложно реализовывать в XML парсерах.

· Существуют другие, обладающие сходными с XML возможностями, текстовые форматы данных, которые обладают более высоким удобством чтения человеком (YAML , JSON, SweetXML).

Язык SGML

Standard Generalized Markup Language (SGML) - это некий метаязык, на котором можно определять язык разметки для документов. SGML — наследник разработанного в 1960 году в IBM языка GML (Generalized Markup Language).

Изначально SGML был разработан для возможности совместного использования машинно-читаемых документов в больших правительственных и аэрокосмических проектах. Также он широко использовался в печатной и издательской сфере, но его сложность затруднила его широкое распространения для повседневного использования.

Три основные части SGML документа, это

1. SGML декларация;

2. Document Type Definition;

3. Содержимое SGML-документа, по крайней мере, должен быть корневой элемент.

SGML предоставляет множество вариантов синтаксической разметки для использования различными приложениями. Изменяя SGML Declaration можно даже отказаться от использования угловых скобок, хотя, этот синтаксис считается стандартным, так называемым concrete reference syntax.

Пример SGML синтаксиса:

<QUOTE TYPE="example">

typically something like <ITALICS>this</ITALICS>

</QUOTE>

И HTML и XML произошли от SGML. HTML это некоторое приложение SGML, а XML это подмножество SGML, разработанное для упрощения процесса машинного разбора документа. Другими приложениями SGML является SGML Docbook (документирование), и «Z Format» (типографика и документирование).

XML-генераторы

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

Пусть, например, нашей задачей является создание формата хранения данных регистрации каких-то происходящих в системе событий (log-файла). В простейшем случае можно ограничиться фиксированием успешных и ошибочных запросов к нашим ресурсам - в таком документе должна присутствовать информация о времени произошедшего события, его результате (удача/ошибка), IP адресе источника запроса, URI ресурса и коде результата.

Наш XML документ может выглядеть следующим образом:

<?xml version="1.0" encoding="koi-8"?>

<log>

<event date=" 27/May/1999:02:32:46 " result="success">

<ip-from> 195.151.62.18 </ip-from>

<method>GET</method>

<url-to> /misc/</url-to>

<response>200</response>

</event>

<event date=" 27/May/1999:02:41:47 "

result="success">

<ip-from> 195.209.248.12 </ip-from>

<method>GET</method>

<url-to> /soft.htm</url-to>

<response>200</response>

</event>

</log>

Структура документа довольно проста - корневым в данном случае является элемент log, каждое произошедшее событие фиксируется в элементе event и описывается при помощи его атрибутов (date - время и result - тип события) и внутренних элементов (method - метод доступа, ip-from - адрес источника, url-to - запрашиваемый ресурс, response - код ответа). Генерацией этого документа может заниматься, например, модуль аутентификации запросов в систему, а использованием - программа обработки регистрационных данных (log viewer).

DTD-определения

Итак, мы создали XML документ и убедились, что набор используемых при этом тэгов позволяет осуществлять любые манипуляции с нашей информацией. В таком случае, для того, чтобы утвердить правила нашего нового языка, т.е. список допустимых элементов, их возможное содержимое и атрибуты, мы должны создать DTD - определения (на момент написания статьи спецификация схем данных для XML- документов еще не утверждена и пока DTD являются единственным стандартным способом описания грамматики).

Вот небольшой пример для нашего XML-документа:

<?xml encoding="koi8-r"?>

<!ELEMENT log (event)+>

<!ELEMENT event (ip-from,method,uri-to,result)>

<!ELEMENT method (#PCDATA)>

<!ELEMENT ip-from (#PCDATA)>

<!ELEMENT url-to (#PCDATA)>

<!ELEMENT response (#PCDATA)>

<!ATTLIST event

result CDATA #IMPLIED

date CDATA #IMPLIED>

Сохранить этот файл под именем log.dtd и включить в XML-документ новую строчку:

<!--DOCTYPE log SYSTEM "log.dtd"-->

Теперь верифицирующий XML-анализатор при обработке документа будет сверять порядок определения элементов и их атрибутов с тем, как это указано у нас в DTD-нотациях и в случае нарушения внутренней структуры выдавать сообщение об ошибке.

Объектная модель документа (DOM)

Одним из самых мощных интерфейсов доступа к содержимому XML документов является Document Object Model - DOM.

Объектная модель XML документов является представлением его внутренней структуры в виде совокупности определенных объектов. Для удобства эти объекты организуются в некоторую древообразную структуру данных - каждый элемент документа может быть отнесен к отдельной ветви, а все его содержимое, в виде набора вложенных элементов, комментариев, секций CDATA и т.д. представляется в этой структуре поддеревьями. Т.к. в любом правильно составленном XML-документе обязательно определен главный элемент, то все содержимое можно рассматривать как поддеревья этого основного элемента, называемого в таком случае корнем дерева документа. Для следующего фрагмента XML документа:

<tree-node>

<node-level1>

<node-level2/>

<node-level2>text</node-level2>

<node-level2/>

</node-level1>

<node-level1>

<node-level2>text</node-level2>

<node-level1>

<node-level2/>

<node-level2><node-level3/></node-level2>

</node-level1>

</tree-node>

дерево элементов выглядит так:


Объектное представление структуры документа не является чем-то новым для разработчиков. Для доступа к содержимому HTML страницы в сценариях давно используется объектно-ориентированный подход, - доступные для Java Script или VBScript элементы HTML документа могли создаваться, модифицироваться и просматриваться при помощи соответствующих объектов. Но их список и набор методов постоянно изменяется и зависит от типа браузера и версии языка. Для того чтобы обеспечить независимый от конкретного языка программирования и типа документа интерфейс доступа к содержимому структурированного документа в рамках W3 консорциума была разработана и официально утверждена спецификация объектной модели DOM Level 1.

DOM - это спецификация универсального платформо- и программно-независимого доступа к содержимому документов. DOM является стандартным способом построения объектной модели любого HTML или XML документа, при помощи которой можно производить поиск нужных фрагментов, создавать, удалять и модифицировать его элементы.

Для описания интерфейсов доступа к содержимому XML документов в спецификации DOM применяется платформонезависимый язык IDL и для использования их необходимо "перевести" на какой-то конкретный язык программирования. С точки зрения разработчиков прикладных программ DOM выглядит как набор объектов с определенными методами и свойствами.

Создание XML-документа

Для создания XML документа в простейшем случае вам не понадобится ничего кроме обычного текстового редактора. Вот пример небольшого XML-документа, используемого вместо обычной записной книжки:

<?xml version="1.0" encoding="koi-8"?>

<notepad>

<note id="1" date="12/04/99" time="13:40">

<subject>Важная деловая встреча </subject>

<importance/>

<text>

Надо встретиться с <person id="1625">

Иваном Ивановичем</person>, предварительно

позвонив ему по телефону <tel>123-12-12</tel>

</text>

</note>

...

<note id="2" date="12/04/99" time="13:58">

<subject>Позвонить домой </subject>

<text>

<tel>124-13-13</tel>

</text>

</note>

</notepad>

При создании собственного языка разметки вы можете придумывать любые названия элементов, (почти любые, т.к. список допустимых символов ограничен и приведен в спецификации XML), соответствующих контексту их использования. В нашем примере приведен лишь один из многочисленных способ создания структуры дневника. В этом и заключается гибкость и расширяемость XML-производных языков - они создаются разработчиком "на лету", согласно его представлениям о структуре документа, и могут затем использоваться универсальными программами просмотра наравне с любыми другими XML-производными языками, т.к. вся необходимая для синтаксического анализа информация заключена внутри документа.

Создавая новый формат, необходимо учитывать тот факт, что документов, "написанных на XML", не может быть в принципе - в любом случае авторы документа для его разметки используют основанный на стандарте XML (т.н. XML-производный) язык, но не сам XML. Поэтому при сохранении созданного файла можно выбрать для него какое-то подходящее названию расширение (например, noteML).

XML может использоваться вами для создания документов какого-то определенного типа и структурой, необходимой для конкретного приложения.

Правила создания

В общем случае XML- документы должны удовлетворять следующим требованиям:

• В заголовке документа помещается объявление XML, в котором указывается язык разметки документа, номер его версии и дополнительная информация.

• Каждый открывающий тэг, определяющий некоторую область данных в документе обязательно должен иметь своего закрывающего "напарника", т.е., в отличие от HTML, нельзя опускать закрывающие тэги.

• В XML учитывается регистр символов.

• Все значения атрибутов, используемых в определении тэгов, должны быть заключены в кавычки.

• Вложенность тэгов в XML строго контролируется, поэтому необходимо следить за порядком следования открывающих и закрывающих тэгов.

• Вся информация, располагающаяся между начальным и конечными тэгами, рассматривается в XML как данные и поэтому учитываются все символы форматирования (т.е. пробелы, переводы строк, табуляции не игнорируются, как в HTML).

Если XML- документ не нарушает приведенные правила, то он называется формально-правильным и все анализаторы, предназначенные для разбора XML- документов, смогут работать с ним корректно.

Однако кроме проверки на формальное соответствие грамматике языка, в документе могут присутствовать средства контроля над содержанием документа, за соблюдением правил, определяющих необходимые соотношений между элементами и формирующих структуру документа. Например, следующий текст, являясь вполне правильным, XML- документом будет абсолютно бессмысленным:

<country><title>Russia</title><city><title>

Novosibirsk</country></title></city>

Для того чтобы обеспечить проверку корректности XML- документов, необходимо использовать анализаторы, производящие такую проверку и называемые верифицирующими.

На сегодняшний день существует два способа контроля правильности XML- документа: DTD – определения (Document Type Definition) и схемы данных (Semantic Schema). Более подробно об использовании DTD и схемах мы поговорим в следующих разделах. В отличие от SGML, определение DTD- правил в XML не является необходимостью, и это обстоятельство позволяет нам создавать любые XML- документы, не ломая пока голову над весьма непростым синтаксисом DTD.

Структура документа

Простейший XML- документ может выглядеть так:

<?xml version="1.0"?>

<list_of_items>

<item id="1"><first/>Первый </item>

<item id="2">Второй <sub_item>подпункт 1

</sub_item></item>

<item id="3">Третий </item>

<item id="4"><last/>Последний </item>

</list_of_items>

Обратите внимание на то, что этот документ очень похож на обычную HTML-страницу. Так же, как и в HTML, инструкции, заключенные в угловые скобки называются тэгами и служат для разметки основного текста документа. В XML существуют открывающие, закрывающие и пустые тэги.

Тело документа XML состоит из элементов разметки (markup) и непосредственно содержимого документа - данных (content). XML- тэги предназначены для определения элементов документа, их атрибутов и других конструкций языка.

Любой XML- документ должен всегда начинаться с инструкции <?xml?>, внутри которой также можно задавать номер версии языка, номер кодовой страницы и другие параметры, необходимые программе-анализатору в процессе разбора документа.

Конструкции языка

Содержимое XML- документа представляет собой набор элементов, секций CDATA, директив анализатора, комментариев, спецсимволов, текстовых данных. Рассмотрим каждый из них подробней.

Элементы данных

Элемент - это структурная единица XML- документа. Заключая слово rose в в тэги <flower> </flower> , мы определяем непустой элемент, называемый <flower>, содержимым которого является rose. В общем случае в качестве содержимого элементов могут выступать как просто какой-то текст, так и другие, вложенные, элементы документа, секции CDATA, инструкции по обработке, комментарии, - т.е. практически любые части XML- документа.

Любой непустой элемент должен состоять из начального, конечного тэгов и данных, между ними заключенных. Например, следующие фрагменты будут являться элементами:

<flower>rose</flower>

<city>Novosibirsk</city> ,

а эти - нет:

<rose>

<flower>

rose

Набором всех элементов, содержащихся в документе, задается его структура и определяются все иерархические соотношения. Плоская модель данных превращается с использованием элементов в сложную иерархическую систему со множеством возможных связей между элементами. Например, в следующем примере мы описываем месторасположение Новосибирских университетов (указываем, что Новосибирский Университет расположен в городе Новосибирске, который, в свою очередь, находится в России), используя для этого вложенность элементов XML :

<country id="Russia">

<cities-list>

<city>

<title>Новосибирск </title>

<state>Siberia</state>

<universities-list>

<university id="2">

<title>Новосибирский Государственный

Технический Университет</title>

<noprivate/>

<address URL="www.nstu.ru"/>

<description>очень хороший институт</description>

</university>

<university id="2">

<title>Новосибирский Государственный

Университет</title>

<noprivate/>

<address URL="www.nsu.ru"/>

<description>тоже не плохой </description>

</university>

</universities-list>

</city>

</cities-list>

</country>

Производя в последствии поиск в этом документе, программа клиента будет опираться на информацию, заложенную в его структуру - используя элементы документа. Т.е. если, например, требуется найти нужный университет в нужном городе, используя приведенный фрагмент документа, то необходимо будет просмотреть содержимое конкретного элемента <university>, находящегося внутри конкретного элемента <city>. Поиск при этом, естественно, будет гораздо более эффективен, чем нахождение нужной последовательности по всему документу.

В XML документе, как правило, определяется хотя бы один элемент, называемый корневым и с него программы-анализаторы начинают просмотр документа. В приведенном примере этим элементом является <country>

В некоторых случаях тэги могут изменять и уточнять семантику тех или иных фрагментов документа, по разному определяя одну и ту же информацию и тем самым предоставляя приложению-анализатору этого документа сведения о контексте использования описываемых данных. Например, прочитав фрагмент <city>Holliwood</city> мы можем догадаться, что речь в этой части документа идет о городе, а вот во фрагменте <restaurant>Holliwood</restaurant> - о забегаловке.

В случае, если элемент не имеет содержимого, т.е. нет данных, которые он должен определять, он называется пустым. Примером пустых элементов в HTML могут служить такие тэги, как <br>, <hr>, <img>. Необходимо только помнить, что начальный и конечные тэги пустого элемента как бы объединяется в один, и надо обязательно ставить косую черту перед закрывающей угловой скобкой (например, <empty/>).

Комментарии

Комментариями является любая область данных, заключенная между последовательностями символов <!-- и --> Комментарии пропускаются анализатором и поэтому при разборе структуры документа в качестве значащей информации не рассматриваются.

Атрибуты

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

<color RGB="true">#ff08ff</color>

<color RGB="false">white</color>

или

<author id=0>Ivan Petrov</author>

Специальные символы

Для того, чтобы включить в документ символ, используемый для определения каких-либо конструкций языка (например, символ угловой скобки) и не вызвать при этом ошибок в процессе разбора такого документа, нужно использовать его специальный символьный либо числовой идентификатор. Например, &lt; , &gt; &quot; или &#036;(десятичная форма записи), &#x1a (шестнадцатеричная) и т.д. Строковые обозначения спецсиволов могут определяться в XML документе при помощи компонентов (entity).

В XML определены два метода записи специальных символов: ссылка на сущность и ссылка по номеру символа. Сущностью (англ. entity) в XML называются именованные данные, обычно текстовые, в частности спецсимволы. Ссылка на сущность (англ. entity references) указывается в том месте, где должна быть сущность и состоит из амперсанда («&»), имени сущности и точки с запятой («;»). В XML есть несколько предопределённых сущностей, таких как «lt» (ссылаться на неё можно написав «&lt;») для левой угловой скобки и «amp» (ссылка — «&amp;») для амперсанда, возможно также определять собственные сущности. Помимо записи с помощью сущностей отдельных символов, их можно использовать для записи часто встречающихся текстовых блоков. Ниже приведён пример использования предопределённой сущности для избежания использования знака амперсанда в названии:

<company-name>AT&amp;T</company-name>

Полный список предопределённых сущностей состоит из &amp; («&»), &lt; («<»), &gt; («>»), &apos; («'»), и &quot; («"») — последние две полезны для записи разделителей внутри значений атрибутов. Определить свои сущности можно в DTD-документе. Иногда бывает необходимо определить неразрывный пробел, который в XML записывается &#160;

Cсылка по номеру символа (англ. numeric character reference) выглядит как ссылка на сущность, но вместо имени сущности указывается символ # и число (в десятичной или шестнадцатеричной записи), являющееся номером символа в кодовой таблице Юникод. Это обычно символы, которые невозможно закодировать напрямую, например буква арабского алфавита в ASCII-кодированном документе. Амперсанд может быть представлен следующим образом:

<company-name>AT&#038;T</company-name>

Директивы анализатора

Инструкции, предназначенные для анализаторов языка, описываются в XML документе при помощи специальных тэгов - <? и ?>;. Программа клиента использует эти инструкции для управления процессом разбора документа. Наиболее часто инструкции используются при определении типа документа (например, <? Xml version=”1.0”?>) или создании пространства имен.

CDATA

Чтобы задать область документа, которую при разборе анализатор будет рассматривать как простой текст, игнорируя любые инструкции и специальные символы, но, в отличии от комментариев, иметь возможность использовать их в приложении, необходимо использовать тэги <![CDATA] и ]]>. Внутри этого блока можно помещать любую информацию, которая может понадобится программе- клиенту для выполнения каких-либо действий (в область CDATA, можно помещать, например, инструкции JavaScript). Естественно, надо следить за тем, чтобы в области, ограниченной этими тэгами не было последовательности символов ]].

Определение типа документа( DTD)

DTD (англ. Document Type Definition - определение типа документа) — язык описания структуры XML-документа.

В XML- документах DTD определяет набор действительных элементов, идентифицирует элементы, которые могут находиться в других элементах, и определяет действительные атрибуты для каждого из них. Синтаксис DTD весьма своеобразен и от автора-разработчика требуются дополнительные усилия при создании таких документов (сложность DTD является одной из причин того, что использование SGML, требующего определение DTD для любого документа, не получило столь широкого распространения). Как уже отмечалось, в XML использовать DTD не обязательно - документы, созданные без этих правил, будут правильно обрабатываться программой-анализатором, если они удовлетворяют основным требованиям синтаксиса XML. Однако контроль за типами элементов и корректностью отношений между ними в этом случае будет полностью возлагаться на автора документа. До тех пор, пока грамматика нового языка не описана, нужно применять специально разработанное программное обеспечение, а не универсальные программы-анализаторы.

В DTD для XML используются следующие типы правил: правила для элементов и их атрибутов, описания категорий (макроопределений), описание форматов бинарных данных. Все они описывают основные конструкции языка - элементы, атрибуты, символьные константы внешние файлы бинарных данных.

Для того чтобы использовать DTD в документе, мы можем или описать его во внешнем файле и при описании DTD просто указать ссылку на этот файл или же непосредственно внутри самого документа выделить область, в которой определить нужные правила. В первом случае в документе указывается имя файла, содержащего DTD- описания:

<?xml version="1.0" standalone="yes" ?>

<! DOCTYPE journal SYSTEM "journal.dtd">

Внутри же документа DTD- декларации включаются следующим образом:

...

<! DOCTYPE journal [

<!ELEMENT journal (contacts, issues, authors)>

...

]>

...

В том случае, если используются одновременно внутренние и внешние описания, то программой-анализатором будут сначала рассматриваться внутренние, т.е. их приоритет выше. При проверке документа XML- процессор в первую очередь ищет DTD внутри документа. Если правила внутри документа не определены и не задан атрибут standalone ="yes" , то программа загрузит указанный внешний файл и правила, находящиеся в нем, будут считаны оттуда. Если же атрибут standalone имеет значение "yes", то использование внешних DTD описаний будет запрещено.

Определение элемента

Элемент в DTD определяется с помощью дескриптора !ELEMENT, в котором указывается название элемента и структура его содержимого.

Например, для элемента <flower> можно определить следующее правило:

<!ELEMENT flower PCDATA>

Ключевое слово ELEMENT указывает, что данной инструкцией будет описываться элемент XML. Внутри этой инструкции задается название элемента (flower) и тип его содержимого.

В определении элемента мы указываем сначала название элемента (flower), а затем его модель содержимого - определяем, какие другие элементы или типы данных могут встречаться внутри него. В данном случае содержимое элемента flower будет определяться при помощи специального маркера PCDATA (что означает parseable character data - любая информация, с которой может работать программа-анализатор). Существует еще две инструкции, определяющие тип содержимого: EMPTY, ANY. Первая указывает на то, что элемент должен быть пустым (например, <red/>), вторая - на то, что содержимое элемента специально не описывается.

Последовательность дочерних для текущего элемента объектов задается в виде списка разделенных запятыми названий элементов. При этом для того, чтобы указать количество повторений включений этих элементов могут использоваться символы +,*, ? :

<!ELEMENT issue (title, author+, table-of-contents?)>

В этом примере указывается, что внутри элемента <issue> должны быть определены элементы title, author и table-of-contents, причем элемент title является обязательным элементом и может встречаться лишь однажды, элемент author может встречаться несколько раз, а элемент table-of-contents является опциональным, т.е. может отсутствовать. В том случае, если существует несколько возможных вариантов содержимого определяемого элемента, их следует разделять при помощи символа "|" :

<!ELEMENT flower (PCDATA | title )*>

Символ * в этом примере указывает на то, что определяемая последовательность внутренних элементов может быть повторена несколько раз или же совсем не использоваться.

Если в определении элемента указывается "смешанное" содержимое, т.е. текстовые данные или набор элементов, то необходимо сначала указать PCDATA, а затем разделенный символом "|" список элементов.

Пример корректного XML- документа:

<?xml version="1.0"?>

<! DOCTYPE journal [

<!ELEMENT contacts (address, tel+, email?)>

<!ELEMENT address (street, appt)>

<!ELEMENT street PCDATA>

<!ELEMENT appt (PCDATA | EMPTY)*>

<!ELEMENT tel PCDATA>

<!ELEMENT email PCDATA>

]>...

<contacts>

<address>

<street>Marks avenue</street>

<appt id="4">

</address>

<tel>12-12-12</tel>

<tel>46-23-62</tel>

<email>info@j.com</email>

</contacts>

Определение атрибутов

Списки атрибутов элемента определяются с помощью ключевого слова !ATTLIST. Внутри него задаются названия атрибутов, типы их значений и дополнительные параметры. Например, для элемента <article> могут быть определены следующие атрибуты:

<!ATTLIST article

id ID #REQUIRED

about CDATA #IMPLIED

type (actual | review | teach ) 'actual' ''

>

В данном примере для элемента article определяются три атрибута: id, about и type, которые имеют типы ID (идентификатор), CDATA и список возможных значений соответственно. Всего существует шесть возможных типов значений атрибута:

CDATA - содержимым документа могут быть любые символьные данные.

ID - определяет уникальный идентификатор элемента в документе.

IDREF (IDREFS) - указывает, что значением атрибута должно выступать название (или несколько таких названий, разделенных пробелами во втором случае) уникального идентификатора определенного в этом документе элемента.

ENTITY (ENTITIES) - значение атрибута должно быть названием (или списком названий, если используется ENTITIES) компонента (макроопределения), определенного в документе.

NMTOKEN (NMTOKENS) - содержимым элемента может быть только одно отдельное слово (т.е. этот параметр является ограниченным вариантом CDATA).

Список допустимых значений - определяется список значений, которые может иметь данный атрибут.

Также в определении атрибута можно использовать следующие параметры:

#REQUIRED - определяет обязательный атрибут, который должен быть задан во всех элементах данного типа.

#IMPLIED - атрибут не является обязательным.

#FIXED "значение" - указывает, что атрибут должен иметь только указанное значение, однако само определение атрибута не является обязательным, но в процессе разбора его значение в любом случае будет передано программе-анализатору. Значение - задает значение атрибута по умолчанию.

Типизация данных

Довольно часто при создании XML- элемента разработчику требуется определить, данные какого типа могут использоваться в качестве его содержимого. Т.е. если мы определяем элемент <last-modified>10.10.98</last-modified>, то хотим быть уверенными, что в документе в этом месте будет находиться строка, представляющая собой дату, а не число или произвольную последовательность символов. Используя типизацию данных, можно создавать элементы, значения которых могут использоваться, например, в качестве параметров SQL- запросов. Программа клиент в этом случае должна знать, к какому типу данных относится текущее значение элемента и в случае соответствия формирует SQL-запрос.

Если в качестве программы на стороне клиента используется верифицирующий XML-процессор, то информацию о типе можно передавать при помощи специально созданного для этого атрибута элемента, имеющего соответствующее DTD- определение. В процессе разбора программа-анализатор передаст значение этого атрибута клиентскому приложению, которое сможет использовать эту информацию должным образом. Например, чтобы указать, что содержимое элемента должно быть длинным целым, можно использовать следующее DTD- определение:

<!ELEMENT counter (PCDATA)>

<!ATTLIST counter data_long CDATA #FIXED "LONG">

Задав атрибуту значение по умолчанию LONG и определив его как FIXED, мы позволили тем самым программе-клиенту получить необходимую информацию о типе содержимого данного элемента, и теперь она может самостоятельно определить соответствие типа этого содержимого указанному в DTD- определении .

Вот пример XML- документа, в котором определяются и используются несколько элементов с различными типами данных:

<!ELEMENT price (PCDATA)>

<!ATTLIST price data_currency CDATA #FIXED "CURRENCY">

<!ELEMENT rooms_num (PCDATA)>

<!ATTLIST rooms_num data_byte CDATA #FIXED "BYTE">

<!ELEMENT floor (PCDATA)>

<!ATTLIST floor data_byte CDATA #FIXED "INTEGER">

<!ELEMENT living_space (PCDATA)>

<!ATTLIST living_space data_float CDATA #FIXED "FLOAT">

<!ELEMENT counter (PCDATA)>

<!ATTLIST counter data_long CDATA #FIXED "LONG">

<!ELEMENT is_tel (PCDATA)>

<!ATTLIST is_tel data_bool CDATA #FIXED "BOOL">

<!ELEMENT house (rooms_num, floor,living_space,

is_tel, counter, price)>

<!ATTLIST house id ID #REQUIED>

...

<house id="0">

<rooms_num>5</rooms_num>

<floor>2</floor>

<living_space>32.5</living_space>

<is_tel>true</is_tel>

<counter>18346</counter>

<price>34 р . 28 к .</price>

</house>

...

Как видно из примера, механизм создания элементов документа при этом нисколько не изменился. Все необходимая для проверки типов данных информация заложена в определения элементов внутри блока DTD.

В заключении хотелось бы отметить, что DTD предоставляет весьма удобный механизм осуществления контроля за содержимым документа. На сегодняшний день, практически все программы просмотра документов Интернет используют DTD-правила. Однако это далеко не единственный способ проверки корректности документа. В настоящий момент в W3 консорциуме находится на рассмотрении новый стандарт языка описания структуры документов, называемый схемами данных. Сейчас идёт отказ от формата по ряду причин:

Во-первых, он использует отличный от XML синтаксис.

Во-вторых, отсутствует типизация узлов.

На смену DTD пришёл стандарт консорциума W3C XML Schema.

Схемы данных

Схемы данных (Schemas) являются альтернативным способом создания правил построения XML-документов. По сравнению с DTD, схемы обладают более мощными средствами для определения сложных структур данных, обеспечивают более понятный способ описания грамматики языка, способны легко модернизироваться и расширяться. Безусловным достоинством схем является также то, что они позволяют описывать правила для XML- документа средствами самого же XML.

Однако это не означает, что схемы могут полностью заменить DTD- описания - этот способ определения грамматики языка используется сейчас практическими всеми верифицирующими анализаторами XML и, более того, сами схемы, как обычные XML- элементы, тоже описываются DTD. Но серьезные возможности нового языка и его относительная простота, безусловно, дают основания утверждать, что будущий стандарт найдет широкое применение в качестве удобного и эффективного средства проверки корректности составления документов.

Внешний вид схем данных

Внешне документы схем очень похожи на те документы XML, с которыми мы уже встречались в предыдущих разделах. Мы размечаем документ при помощи специальных элементов, выполняющих в схемах роль инструкций. Эти инструкции составляют набор правил, используя которые, программа-клиент будет делать вывод о том, корректен документ или нет. Схема данных, например, может выглядеть следующем образом:

<schema id="OurSchema">

<elementType id="#title">

<string/>

</elementType>

<elementType id="photo">

<element type="#title">

<attribute name="src"/>

</elementType>

<elementType id="gallery">

<element type="#photo">

</elementType>

</schema>

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

<gallery>

<photo id="1"><title>My computer</title></photo>

<photo id="2"><title>My family</title></photo>

<photo id="3"><title>My dog</title></photo>

</gallery> ,

а некорректным этот:

<gallery>

<photo id="1"/>

<photo index="2"><title>My family</title></photo>

<photo index="3"><title> My dog </title><dogname>

Sharik</dogname></photo>

</gallery>

Область схемы данных

Создавая схемы данных, мы определяем в документе специальный элемент, <schema>, внутри которого содержатся описания правил:

<schema id="OurSchema">

<!-- последовательность инструкций -->

</schema>

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

<?XML version='1.0' ?>

<?xml:namespace

href="http://www.mrcpk.nstu.ru/schemas/" as="s"/?>

<s:schema id="OurSchema">

<!-- последовательность инструкций -->

</s:schema>

Описание элементов

Для определения класса элемента, к которому в дальнейшем будут применяться инструкции, описывающие его содержимое и структуру, предназначен специальный элемент схемы elementType:

<elementType id="issue">

<descript>Элемент содержит информацию об очередном

выпуске журнала</descript>

</elementType>

Название элемента задается атрибутом id. Все дальнейшие инструкции, которые относятся к описываемому классу, определяют его внутреннюю структуру и набор допустимых данных, содержатся внутри блока, заданного тэгами <elementType> и </elementType>. Мы рассмотрим эти инструкции чуть позже.

Как видно из примера, при определении класса элемента, можно также использовать комментарии к нему, которые заключаются в тэги <descript></descript>.

Атрибуты элемента

Для того, чтобы в описании элемента определить его атрибуты и описать свойства этих атрибутов мы должны использовать элемент attribute:

<elementType id="photo">

<attribute name="src"/>

<empty/>

</elementType>

В данном примере элементу <photo> определяется атрибут src, значением которого может быть любая последовательность разрешенных символов:

<photo src="0"/>

<photo src="some text">

Подобно DTD, схемы данных позволяют устанавливать ограничения на значения и способ использования атрибутов. Для этого в дескрипторе <attribute> необходимо использовать параметр atttype.

Например, если мы хотим указать, что значение атрибута должно использоваться программой-анализатором как уникальный идентификатор, то нам необходимо создать следующее правило:

<elementType id="bouquet">

<attribute name="id" atttype="ID">

</elementType>

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

<attribute name="flower" atttype="ENUMERATION"

values="red green blue" default="red">

Для приведенных примеров корректным будет являться следующий фрагмент XML-документа:

<bouquet id="0">

<flower color="red">rose</flower>

<flower color="green">leaf</flower>

<flower color="blue">bluet</flower>

</bouquet>

Модель содержимого элемента

Под моделью содержимого в схеме данных понимают описание всех допустимых объектов XML- документа, использование которых внутри данного элемента является корректным. Модель содержимого определяется инструкциями, расположенными внутри блока <elementType>:

<elementType id="article">

<attribute name="id" atttype="ID">

<element type="#title">

<string/>

</elementType>

Для этого правила корректным будет являться следующий фрагмент документа:

<article id="0">

<title>Психи и маньяки в Интернет</title>

</article>

Вложенные элементы описываются при помощи инструкции element, в которой параметром type указывается класс объекта - ссылка на его определение:

<elementType id="article">

<element type="#title"/>

<element type="#author"/>

</elementType>

Если требуется указать режим использования вложенного элемента, то надо определить параметр occurs:

<elementType id="article">

<element type="#title" occurs="REQUIRED"/>

<element type="#author" occurs="OPTIONAL"/>

<element type="#subject" occurs="ONEORMORE"/>

</elementType>

Возможные значения этого параметра таковы:

REQUIRED - элемент должен быть обязательно определен.

OPTIONAL - использование элемента не является обязательным.

ZEROORMORE - вложенный элемент может встречаться несколько раз или ни разу.

ONEORMORE - элемент должен встречаться хотя бы один раз.

Примеры правильных XML-документов, использующих приведенную выше схему:

<article>

<title>Зачем он нужен , XML?</title>

<author>Иван Петров </author>

<subject>Что такое XML</subject>

<subject>нужен ли он нам</subject>

</article>

или

<article>

<title>Зачем он нужен , XML?</title>

<subject>Что такое XML</subject>

</article>

Кроме элементов, содержимым XML-документа могут также является обычный текст и области CDATA. Для обозначения типов содержимого текущего элемента в схемах используются следующие инструкции:

<string/> - указывает на то, что содержимым элемента является только свободная текстовая информация(секция PCDATA) :

<elementType id="flower">

<string/>

</elementType>

<any/> - указывает на то, что содержимым элемента должны являться только элементы, без текста, незаключенного ни в один элемент:

<elementType id="issue">

<any/>

</elementType>

<mixed> - любое сочетание элементов и текста

<elementType id="contacts">

<mixed/>

</elementType>

<empty> - пустой элемент

Пример:

<elementType id="title">

<string/>

</elementType>

<elementType id="chapter">

<string/>

</elementType>

<elementType id="chapters-list">

<any/>

</elementType>

<elementType id="content">

<element type="#chapters-list" occurs="OPTIONAL">

</elementType>

<elementType id="article">

<mixed><element type="#title"></mixed>

<element type="#content" occurs="OPTIONAL">

</elementType>

Иерархия классов

Для того, чтобы при описании класса ограничить список объектов, которые могут являться родительскими для данного элемента, необходимо использовать элемент схемы domain.

Инструкция <domain> указывает, что текущий объект должен определяться строго внутри элемента, заданного этим тэгом. Например, в следующем фрагменте указывается, что элемент <author> может быть определен строго внутри тэга <article>:

<elementType id="author">

<element type="#lastname">

<element type="#firstname">

<domain type="#article"/>

</elementType>

Ограничения на значения

Значения элементов могут быть ограничены при помощи тэгов <min> и <max>;:

<elementType id="room">

<element type="#floor"><min>0</min><max>100</max>

</elementType>

Внутри этих элементов могут указываться и символьные ограничения:

<elementType id="line">

<element type="#character"><min>A</min><max>Z</max>

</elementType>

Использование правил из внешних схем

Схема может использовать элементы и атрибуты из других схем. Для этого надо использовать атрибут href, в котором указывается название внешней схемы. Например:

<?XML version='1.0' ?>

<?xml:namespace name="urn:uuid:BDC6E3F0-6DA3-11d1-

A2A3-00AA00C14882/" as="s"/?>

<s:schema>

<elementType id="author">

<string/>

</elementType>

<elementType id="title">

<string/>

</elementType>

<elementType id="Book">

<element type="#title" occurs="OPTIONAL"/>

<element type="#author" occurs="ONEORMORE"/>

<element href="http://mrcpk.org/" />

</elementType></s:schema>

</elementType>

</s:schema>

Типы данных

В разделе, посвященном DTD, мы уже выяснили, для чего программе-клиенту необходима информация о формате данных содержимого элемента. В схемах существует возможность задавать тот или иной тип данных, используя при определении элемента директиву <datatype> с указанием конкретного типа:

<elementType id="counter">

<datatype dt="int">

</elementType>

В DTD мы должны были создать атрибут с конкретным названием, определяющим операцию назначения формата данных, и значением, определенным как fixed. Использование элемента <datatype> позволяет указывать это автоматически, но для обеспечения программной независимости необходимо сначала договориться об обозначениях типов данных (значения, которые должны передаваться параметру dt элемента dataype. В любом случае, как и прежде, все необходимые действия, связанные с конкретной интерпретацией данных, содержащихся в документе, осуществляются программой-клиентом и определяются логикой его работы. В разделе, посвященном DTD, мы уже рассматривали пример XML- документа, реализующего описанные нами возможности. Вот как выглядел бы этот пример при использовании схем данных:

<schema id="someschema">

<elementType id="#rooms_num">

<string/>

<datatype dt="int">

</schema>

<elementType id="#floor">

<string/>

<datatype dt="int">

</schema>

<elementType id="#living_space">

<string/>

<datatype dt="float">

</schema>

<elementType id="#is_tel">

<string/>

<datatype dt="boolean">

</schema>

<elementType id="#counter">

<string/>

<datatype dt="float">

</schema>

<elementType id="#price">

<string/>

<datatype dt="float">

</schema>

<elementType id="#comments">

<string/>

<datatype dt="string">

</schema>

<elementType id="#house">

<element type="#rooms_num"occurs="ONEORMORE"/>

<element type="#floor" occurs="ONEORMORE"/>

<element type="#living_space" occurs="ONEORMORE"/>

<element type="#is_tel" occurs="OPTIONAL"/>

<element type="#counter" occurs="ONEORMORE"/>

<element type="#price" occurs="ONEORMORE"/>

<element type="#comments" occurs="OPTIONAL"/>

</elementType>

</schema>

...

<house id="0">

<rooms_num>5</rooms_num>

<floor>2</floor>

<living_space>32.5</living_space>

<is_tel>true</is_tel>

<counter>18346</counter>

<price>34.28</price>

<comments>С видом на северный полюс </comments>

</house>

...

Язык запросов XQuery

XQuery — язык запросов, разработанный для обработки данных в формате XML. XQuery использует XML как свою модель данных.

Консорциум World Wide Web Consortium (W3C) образовал рабочую группу для разработки языка запросов к источникам данных, представленных на языке XML. Этот язык запросов, получивший название XQuery, развивается до сих пор и описан в серии предварительных документов. XQuery — функциональный язык, состоящий из нескольких видов выражений, которые могут использоваться в разных сочетаниях. Язык базируется на системе типов XML Schema и совместим с другими стандартами, связанными с XML.

Язык XML все чаще применяется в качестве формата для обмена информацией между разными приложениями в Internet. Популярность XML во многом объясняется его гибкостью при представлении разных видов информации. Применение тегов делает XML-данные самоописываемыми, а расширяемая природа XML позволяет определять новые виды специализированных документов. По мере роста значимости XML создается целая серия стандартов, многие из которых были подготовлены консорциумом W3C . Так, XML Schema обеспечивает нотацию для определения новых типов элементов и документов; XML Path Language (XPath) — нотацию для выбора элементов в документе XML; Extensible Stylesheet Language Transformations (XSLT) — нотацию для преобразования документов XML из одного представления в другое.

XML позволяет приложениям обмениваться данными в стандартном формате, не зависящем от способа их хранения. Скажем, одно приложение может использовать естественный для XML формат хранения, а другое — хранить данные в реляционной базе данных. Поскольку XML все больше утверждается в роли стандарта для обмена данными, естественно, что запросы, поступающие от приложений, должны быть выражены как запросы к данным в формате XML. Это вызывает потребность в языке запросов, явно ориентированном на источники XML-данных. В октябре 1999 года W3C образовал рабочую группу XML Query Working Group с целью разработки такого языка запросов, получившего название XQuery.

В XML-документах имеется внутренний порядок, а реляционные данные неупорядочены, если не принимать во внимание те случаи, когда порядок можно определить на основе значений данных. Реляционные данные обычно являются «плотными» (т.е. почти в каждом столбце имеется значение), а отсутствующая информация в реляционных системах часто представляется специальным значением null. XML-данные часто бывают «разреженными», а отсутствие информации может представляться отсутствием элемента. По этим и другим причинам имеющиеся языки реляционных запросов не подходят напрямую для запросов XML-данных.

На разработку XQuery влияет целый ряд факторов. Возможно, важнее всего совместимость с существующими стандартами W3C, в том числе, XML Schema, XSLT, XPath и сам XML. В частности, язык XPath настолько тесно связан с XQuery, что XQuery определяется как надмножество XPath. В начальном виде XQuery устремлен только на извлечение информации и не включает средств для модификации существующих документов XML

Модель данных

Формально входные и выходные данные XQuery определяются в терминах модели данных. «Запросная» модель данных обеспечивает абстрактное представление одного или нескольких документах или фрагментов XML-документов. Модель данных опирается на понятие последовательности. Последовательность (sequence) — это упорядоченный набор нулевого или большего числа объектов. Объект (item) может быть узлом или атомарным значением. Атомарное значение (atomic value) — экземпляр одного из встроенных типов данных, определенных в XML Schema, таких как строки, целые и десятичные числа, даты. Узел (node) соответствует одному из семи видов: элементы, атрибуты, тексты, документы, комментарии, команды обработки и пространства имен. Узел может иметь другие узлы в качестве потомков, что позволяет образовывать одну или несколько иерархий узлов. Некоторые виды узлов, такие как элементы и атрибуты, имеют имена или типизированные значения, либо и то, и другое. Типизированное значение (typed value) — это последовательность из нуля или большего числа атомарных значений. Узлы индивидуальны (т. е. два узла можно различить, даже если они имеют одинаковые имена и значения), но атомарные величины такой индивидуальностью не обладают. Для всех узлов иерархии имеется полный порядок, называемый порядком документа (document order), в соответствии с которым каждый узел предшествует своему потомку. Порядок документа соответствует порядку, в котором следовали бы узлы, если бы иерархия узлов представлялась в формате XML. Порядок документа между узлами в разных иерархиях определяется в реализации, но он должен быть последовательным, т.е. все узлы одной иерархии должны располагаться либо до, либо после всех узлов другой иерархии.

Последовательности могут быть неоднородными, т.е. могут содержать смесь узлов и атомарных значений разного типа. Однако последовательность никогда не может быть объектом в другой последовательности. Все операции, создающие последовательность, определены так, что результат операции — одноуровневая последовательность. Не проводится различие между объектом и последовательностью единичной длины, т.е. узел и атомарное значение величины считаются идентичными последовательности единичной длины, содержащей эти узел или атомарное значение.

Допускаются последовательности нулевой длины, и иногда они используются для представления отсутствующей или неизвестной информации, во многом так же, как в реляционных системах используются неопределенные значения.

Помимо последовательностей в запросной модели данных определяется специальное значение, называемое значением ошибки (error value), которое является результатом вычисления выражения, содержащего ошибку. Значение ошибки не может присутствовать в последовательности вместе с каким-либо другим значением.

Входные XML-документы могут быть преобразованы в запросную модель данных с помощью процесса, называемого проверкой корректности по схеме (schema validation). Этот процесс выполняет грамматический разбор документа, проверяет его корректность в соответствии с некоторой схемой и представляет документ в виде иерархии узлов и атомарных значений, помеченных типом полученным из схемы. Если входной документ не имеет схемы, проверка его корректности выполняется в соответствии с используемой по умолчанию рекомендательной схемой, которая присваивает родовые типы — узлы маркируются как anyType, а атомарные величины — как anySimpleType.

Результат запроса может быть преобразован из запросной модели данных запросов в XML-представление с помощью процесса, называемого сериализацией (serialization). Следует отметить, что результат запроса не всегда является правильно построенным XML-документом. Например, запрос может возвращать атомарное значение или последовательность элементов, не имеющих общего предка.

Иллюстрация запросной модели

Чтобы проиллюстрировать запросную модель данных и обеспечить основу для последующих примеров, рассмотрим небольшую базу данных, содержащую данные интерактивного аукциона. Эта база данных содержит два XML-документа с именами items.xml и bids.xml.

Документ items.xml содержит корневой элемент с именем items, который, в свою очередь, содержит элемент item для каждого из товаров, предложенных к продаже на аукционе. Каждый элемент item имеет атрибут status и подэлементы с именами itemno, seller, description, reserve-price и end-date. Элемент reserve-price указывает минимальную продажную цену, установленную владельцем товара, а end-date определяет дату окончания торгов.

Документ bids.xml содержит корневой элемент с именем bids, который, в свою очередь, содержит элемент bid для каждой ставки, которая предлагается за товар. Каждый элемент bid имеет подэлементы с именами itemno, bidder, bid-amount и bid-date.

Рис. 1. Представление модели данных из items.xml

На рис. 1 и 2 показаны модельные представления документов items.xml и bids.xml соответственно (включающие только образцы товара и ставки). Круги, помеченные буквами D, E, A и T, обозначают узлы документов, элементов, атрибутов и тестов соответственно.

Рис. 2. Представление модели данных из bids.xml

Выражения XQuery

Основы

Подобно XML и XPath, в XQuery различаются прописные и строчные буквы, а все ключевые слова состоят из строчных букв. Символы, заключенные между «{—» и «—}» считаются комментариями и при обработке запроса игнорируются (конечно, кроме тех случаев, когда они входят в строку, заключенную в кавычки, и считаются частью этой строки).

Простейший вид выражения XQuery — литерал (literal), который представляет атомарное значение.

Атомарные значения других типов могут создаваться путем вызова конструкторов. Конструктор (constructor) представляет собой функцию, которая создает значение определенного типа на основе строки, содержащей лексическое представление значения этого типа. В общем случае конструктор имеет то же имя, что и тип, значения которого он конструирует. Ниже конструктор используется для создания значения типа date.

date(«2002-5-31»)

Переменная (variable) в XQuery — имя, начинающееся со знака доллара. Переменная может быть связана со значением и использоваться в выражении для представления этого значения. Один из способов связывания переменной состоит в использовании выражения LET, которое связывает одну или несколько переменных, а затем вычисляет внутреннее выражение. Значение выражения LET — результат вычисления внутреннего выражения со связанными переменными. Следующий пример иллюстрирует выражение LET, которое возвращает последовательность 1, 2, 3.

let $start := 1, $stop := 3

return $start to $stop

Выражение LET — частный случай выражения FLWR (for, let, where, return), которое обеспечивает дополнительные способы связывания переменных.

Выражения пути

Выражения пути в XQuery базируются на синтаксисе XPath. Выражение пути состоит из серии шагов, разделенных символом слэша («/»). Результат каждого шага — последовательность узлов. Значение выражения пути — последовательность узлов, которая формируется на последнем шаге.

Каждый шаг вычисляется в контексте некоторого узла, называемого контекстным узлом (context node). В общем случае шаг может быть любым выражением, возвращающим последовательность узлов. Один из важных видов шага, называемый осевым шагом (axis step), можно считать перемещением от контекстного узла по иерархии узлов в некотором направлении, называемом осью (axis). При перемещении по указанной оси осевой шаг выбирает узлы, которые удовлетворяют критерию выбора. Критерий выбора может выбирать узлы на основе их имен, положения по отношению к контекстному узлу или предикату, базирующемуся на значении узла. В XPath определяются 13 осей, и часть из них или все будут поддерживаться и в XQuery. Пока планируется реализовать в XQuery поддержку шести осей: child, descendant, parent, attribute, self и descendant-or-self.

Выражения пути могут быть записаны в полном или в сокращенном синтаксисе. Полный синтаксис для осевого шага предусматривает указание оси и критерия выбора, разделенных парой двоеточий. Q1 иллюстрирует четырехшаговое выражение пути, оформленное в полном синтаксисе. На первом шаге вызывается встроенная функция document, которая возвращает узел-документ документа items.xml. Второй шаг — осевой шаг, который находит всех потомков узла-документа («*» выбирает все узлы на данной оси; в данном случае будет выбран единственный узел-элемент с именем items). Третий шаг снова выполняет поиск вдоль оси child, чтобы найти на следующем уровне все элементы-потомки с именем item, которые, в свою очередь, имеют потомков с именем seller и значением «Smith». Результатом третьего шага является последовательность узлов-элементов item. Каждый из этих узлов item служит контекстным узлом для четвертого шага, который опять предусматривает поиск по оси child элементов description, являющихся потомками данного item. Окончательный результат выражения пути — результат четвертого шага: последовательность узлов-элементов description, перечисленных в порядке документа.

(Q1) Перечислить описания всех товаров, предлагаемых к продаже Смитом.

document("items.xml")/child::*

/child::item [child::seller = "Smith"]

/child::description

На практике, выражения пути часто записываются с помощью сокращенного синтаксиса. Пожалуй, наиболее важным является то, что спецификатор оси может быть пропущен в том случае, когда используется ось child. Поскольку child является наиболее часто используемой осью, такое сокращение помогает сократить длину многих выражений пути. К примеру, Q1 можно сократить следующим образом:

document("items.xml")

/*/item[seller = "Smith"]/description

Разделение двух шагов двойным, а не одинарным слэшем означает, что второй шаг может выполнять поиск в нескольких уровнях иерархии, используя для этого ось descendants, а не одноуровневую ось child. Так, Q2 выполняет поиск элементов description, которые являются потомками (необязательно прямыми) корневого узла данного документа. Результат Q2 — это последовательность узлов-элементов, которые могут, в принципе, быть найдены на различных уровнях иерархии узлов (хотя в нашем примере все узлы description находятся на одном и том же уровне).

(Q2) Перечислить все элементы описания товаров, имеющиеся в документе items.xml.

document(«items.xml»)//description

В выражении пути одинарная точка («.») указывает на контекстный узел, а две последовательные точки («..») — на предка контекстного узла. Эти нотации представляют собой сокращенное указание осей self и axes соответственно. Имена, присутствующие в выражениях пути, как правило, интерпретируются как имена узлов-элементов, однако если имя имеет префикс «@», оно интерпретируется как имя узла-атрибута. Это сокращение для шага, который выполняет поиск вдоль оси attribute. Эти аббревиатуры иллюстрируются в Q3, где поиск начинается с узла, связанного с переменной $description, вдоль оси parent к родительскому узлу item, а затем — вдоль оси attribute в поисках атрибута с именем status. Результатом Q3 является единственный узел-атрибут.

(Q3) Найти атрибут статуса для товара, который является предком данного описания товара.

$description/../@status

Предикаты

В XQuery предикат (predicate) — это заключенное в квадратные скобки выражение, которое используется для фильтрации последовательности значений. Предикаты часто применяются в шагах выражения пути. Например, в шаге item[seller = «Smith»] фраза seller = «Smith» — это предикат, который применяется для выбора определенных узлов item и отбрасывания остальных. Будем называть объекты последовательности, фильтруемые с помощью предиката, объектами-кандидатами. Предикат вычисляется для каждого объекта-кандидата с использованием этого объекта-кандидата в качестве контекстного объекта для вычисления выражения предиката. Термин «контекстный объект» — это обобщение термина «контекстный узел», и ему может соответствовать как узел, так и атомарное значение. В предикатном выражении одинарная точка («.») обозначает контекстный объект. Каждый объект-кандидат выбирается или отвергается в соответствии со следующими правилами.

Если в результате вычисления предикатного выражения получается булевское значение, то объект-кандидат выбирается в том случае, если значение предикатного выражение равно true. Этот тип предиката иллюстрируется в примере, где выбираются узлы item, имеющие узел-потомок reserve-price, чье значение больше 1000:

item [reserve-price > 1000]

Если результатом вычисления предикатного выражения является число, то объект-кандидат выбирается в том случае, если его порядковый номер в списке объектов-кандидатов равен этому числу. Такой тип предиката представлен в примере, где выбирается пятый узел item по оси child:

item [5]

Если в результате вычисления предикатного выражения получается пустая последовательность, объект-кандидат отвергается. Однако если результат вычисления предикатного выражения представляет собой последовательность, содержащую хотя бы один узел, объект-кандидат выбирается. Такая форма предиката может применяться для проверки существования узла-потомка, удовлетворяющего некоторому условию. Это иллюстрирует пример, где выбираются узлы item, у которых имеется узел-потомок reserve-price, вне зависимости от его значения:

item [reserve-price]

Внутри предикатов часто используется несколько видов операций и функций.

Операции сравнения значений (value comparison operator): eq, ne, lt, le, gt, ge. Эти операции могут сравнивать два скалярных значения, но порождают ошибку, если любой из операндов является последовательностью с длиной, большей единицы. Если один из операндов — узел, то прежде, чем выполнить сравнение, операция сравнения значений извлекает его значение. Например, item[reserve-price gt 1000] выбирает узел item только в том случае, если он имеет в точности один узел-потомок reserve-price со значением, большим 1000.

Общие операции сравнения (general comparison operator): =, !=, >, >=, <, <=. Эти операции могут работать с операндами, которые представляются собой последовательности, при условии неявного наличия семантики «существования» для обоих операндов. Как и операции сравнения значений, общие операции сравнения автоматически извлекают значения узлов. Например, item[reserve-price = 1000] выбирает узел item, если у него имеется хотя бы один узел-потомок со значением, большим 1000.

Операции сравнения узлов (node comparison operator): is и isnot. Эти операторы определяют идентичность двух узлов. Например, $node1 is $node2 принимает значение «истина», если переменные $node1 и $node2 связаны с одним и тем же узлом (т. е. для обеих переменных узел один и тот же).

Операции сравнения порядка (order comparison operator). Эти операции сравнивают позиции двух узлов. Например, $node1 << $node2 принимает значенией true, если узел, связанный с $node1, в порядке документа встречается раньше, чем узел, связанный с $node2.

Логические операции (logical operator): and и or. Эти операции могут использоваться для объединения логических условий в предикате. Например, следующий предикат выбирает узлы item, имеющие ровно один элемент-потомок seller со значением «Smith», а также, по крайней мере, один элемент-потомок reserve-price с любым значением.

item [seller eq «Smith» and reserve-price].

Отрицание (negation): not. Это скорее функция, а не операция. Она служит для инвертирования булевых величин.

Во всех приведенных примерах имена элементов и атрибутов были простыми идентификаторами. Однако в соответствии с рекомендацией XML Namespace [19], элементами и атрибутам позволяется иметь имена, состоящие из двух частей, где первая часть — префикс пространства имен, за которым следует двоеточие. Имя, имеющее префикс пространства имен, называется QName. Каждый префикс пространства имен должен быть связан с URI (универсальный идентификатор ресурсов), который уникальным образом определяет пространство имен. Это соглашение позволяет каждому приложению определять имена в своем собственном пространстве, не опасаясь коллизий с именами, определенными другими приложениями, что дает возможность однозначно ссылаться на имена, указываемые в различных приложениях. Если бы префикс auction был связан с URI пространства имен нашего приложения для проведения интерактивного аукциона, то шаг item [reserve-price > 1000] мог бы быть записан с помощью QName следующим образом:

auction:item [auction:reserve-price > 1000]

Процесс связывания префикса с URI пространства имен описан в предпоследнем разделе. В большинстве наших примеров используются одиночные имена, а не QName. Эти примеры реалистичны, поскольку XQuery обеспечивает способ указания пространства имен для запроса по умолчанию. Этот подход позволяет не использовать в запросах QName, если не нужно ссылаться на имена из других пространств имен.

Конструкторы элементов

Выражения пути — мощное средство, но им свойственно существенное ограничение: они способны выбирать только существующие узлы. В полном языке запросов необходимо наличие средства конструирования новых элементов и атрибутов, а также возможность указания их информационного наполнения и взаимосвязи. Это обеспечивается в XQuery с помощью вида выражения, называемого конструктором элементов (element constructor).

Простейший конструктор элементов создает элемент в полном соответствии с синтаксисом XML. Например, следующее выражение конструирует элемент с именем highbid, имеющий атрибут status и два элемента-потомка с именами itemno и bid-amount.

<highbid status = «pending»>

<itemno>4871</itemno>

<bid-amount>250.00</bid-amount>

</highbid>

В этом примере значения элементов и атрибутов — константы. Однако во многих случаях необходимо создавать элемент или атрибут, значением которых является вычисляемое выражение. Выражение, заключенное в фигурные скобки, необходимо вычислить, а не трактовать как символьный текст. В конструкторе элемента это выражение вычисляется и заменяется своим значением. В следующем примере значения элементов и атрибутов вычисляются. Переменные $s, $i и $bids, используемые в этих выражениях, должны быть связаны с некоторыми выражениями.

<highbid status = «{$s}»>

<itemno>{$i}</itemno>

<bid-amount>

{max($bids[itemno = $i]/bid-amount)}

</bid-amount>

</highbid>

В следующем примере конструктор элементов содержит выражение, заключенное в фигурные скобки, которое генерирует один атрибут и два подэлемента. Переменная $b должна быть связана с некоторым выражением.

<highbid>

{

$ b/@ status

$b/itemno

$b/bid-amount

}

</highbid>

Узел-элемент, созданный конструктором элемента, является новым узлом, обладающим собственной индивидуальностью. Если, как в приведенном примере, вновь созданный элемент имеет узлы-потомки и атрибуты, порожденные из существующих узлов, то новые узлы-потомки и атрибуты являются копиями узлов, из которых они были получены, но как узлы они индивидуальны.

В приведенных примерах конструкторов элементов, хотя содержимое элементов может быть вычисляемым, имя конструируемого элемента — известная константа. Однако иногда необходимо сконструировать элемент, имя которого, как и его содержимое, вычисляется. Для этого в XQuery определяется специальный вид конструктора, называемого вычисляемым конструктором элемента (computed element constructor). Он состоит из ключевого слова element, за которым следуют два выражения в фигурных скобках — первое вычисляет имя элемента, а второе — его содержимое.

Чтобы привести пример использования вычисляемого конструктора, предположим, что переменная $e связана с элементом, имеющим числовое значение. Нам нужно сконструировать новый элемент, имеющий то же имя, что и $e, и те же атрибуты, что у $e, но его значение должно быть вдвое больше значения $e. Этого можно добиться с помощью выражения, в котором функция data используется для получения числового значения исходного узла.

element

{name($e)}

{$e/@*, data($e)*2}

Подобно вычисляемому конструктору элемента, в XQuery обеспечивается вычисляемый конструктор атрибута (computed attribute constructor), состоит из ключевого слова attribute, за которым следуют два выражения в фигурных скобках — первое вычисляет имя атрибута, а второе — значение. Конструктор атрибута может использоваться везде, где допустим атрибут. Следующий конструктор атрибута на основе связанной переменной $p мог бы сгенерировать атрибут, который выглядит как father = «Frank» или mother = «Mary».

attribute

{if $p/sex = "M" then "father" else "mother"}

{$p/name}

Итерация и сортировка

Итерация — важная часть языка запросов. XQuery предлагает способ выполнять итерацию над последовательностью значений, по очереди связывая переменную с каждым значением и вычисляя выражения для каждого связывания переменной.

В наиболее простой форме итерация в XQuery задается оператором for, в котором указывается имя переменной и предоставляется последовательность значений, над которой переменная итерируется. Далее указывается оператор return, который содержит выражение, вычисляемое для каждого связывания переменной; см. ниже.

for $n in (2, 3) return $n + 1

Результатом этого итеративного выражения будет последовательность (3, 4).

В операторе for можно указывать более одной переменной с последовательностью итерации для каждой из них. Такой оператор порождает кортежи связываний переменных, которые образуют декартово произведение итерационных последовательностей. Если не указано иное, кортежи связываний генерируются в порядке, сохраняющем порядок итерационных последовательностей, с использованием самой левой переменной как «самый внешний цикл», а самую правую — как «самый внутренний цикл». В примере оператор for содержит две переменные и две итерационные последовательности.

for $m in (2, 3), $n in (5, 10)

return <fact>{$m} times {$n} is

{$m * $n} </fact>

В результате получается следующая последовательность из четырех элементов.

<fact>2 times 5 is 10 </fact>

<fact>2 times 10 is 20 </fact>

<fact>3 times 5 is 15 </fact>

<fact>3 times 10 is 30</fact>

Операторы for и let — частные случаи более общего выражения, называемого FLWR. В наболее общем виде выражение FLWR может иметь несколько операторов for, несколько операторов let, необязательный оператор where, а также оператор return. Функция операторов for и let — связывание переменных. Каждый из них содержит одну или несколько переменных и выражение, присваиваемое каждой переменной. Результатом вычисления выражений являются последовательности, и выражения могут содержать ссылки на переменные, для которых связывание было выполнено в предыдущих операторах. Оператор for итерирует каждую переменную над ассоциированной с ней последовательностью, связывая переменную по очереди с каждым объектом последовательности, а как оператор let связывает каждую переменную сразу со всей ассоциированной последовательностью. Это различие иллюстрируется следующей парой операторов.

for $i in (1 to 3)

let $j := (1 to $i)

Эта пара операторов не является полным выражением FLWR, поскольку в нем отсутствует условие return. Операторы for и let просто порождают последовательность кортежей связываний. Приведенный выше пример порождает следующую последовательность из трех пар связываний.

$i = 1, $j = 1

$i = 2, $j = (1,2)

$i = 3, $j = (1,2,3)

В общем случае, число кортежей связывания, порождаемых серией операторов for и let, равняется произведению мощностей выражений итерации в операторах for. Оператор let при отсутствии оператора for, конечно, порождает только один кортеж связывания.

Кортежи связывания, порожденные операторами for и let в FLWR-выражении, фильтруются в соответствии с необязательным условием where. Оператор where содержит выражение, которое вычисляется для каждого кортежа связывания. Если значением выражения where являются булевское значение true или непустая последовательность («проверка существования»), то кортеж связываний принимается; в противном случае он отвергается.

Затем в выражении FLWR вычисляется оператор return по очереди и по одному разу для каждого оставшегося после проверки условия where кортежа связывания. Результаты вычислений объединяется в последовательность, которая и является результатом выражения FLWR.

Возможности FLWR иллюстрируются в запросе к базе данных аукциона Q4.

(Q4) Для каждого товара, который имеет более десяти ставок, создать элемент popular-item, содержащий номер товара, описание и число ставок.

for $i in document("items.xml")/*/item

let $b := document("bids.xml")

/*/ bid[itemno = $i/itemno]

where count ($b) > 10

return

<popular-item>

{

$i/itemno,

$i/description,

<bid-count> {count($b)} </ bid-count>

}

</popular-item>

Операторы for и let порождают пару связывания для каждого item в items.xml. В каждой паре связывания $i связан с товаром, а $b — с последовательностью, содержащей все ставки для этого товара. Оператор where оставляет только те связанные кортежи, в которых $b содержит более десяти ставок. Затем оператор return для каждого из этих связываний генерирует выходной элемент, содержащий номер товара, описание и число ставок.

По умолчанию, порядок выходной последовательности выражения FLWR соответствует порядку итерационных последовательностей. Перед любым выражением может стоять префиксная операция unordered, указывающая, что порядок результата не имеет значения. Такое указание повышает гибкость реализации, позволяя оптимизировать вычисление выражения.

Конечно, каждое выражение упорядочивания должно возвращать единственный результат, и эти результаты должны быть сравнимы с помощью оператора gt. В случае применения условия sortby пустая последовательность может считаться либо больше любого другого значения, либо меньше любого другого значения — как то определит пользователь.

Условие sortby часто полезно для переупорядочивания результатов выражения FLWR. Если необходимо отсортировать по убыванию bid-count элементы popular-item, сгенерированные в запросе Q4, то в конец Q4 можно добавить следующий оператор.

sortby bid-count descending

Важно понимать, что sortby не является частью выражения FLWR, а представляет собой отдельный вид выражений XQuery, который может использоваться для переупорядочивания любой последовательности, вне зависимости от того, сгенерирована она выражением FLWR или нет. Однако если после выражения FLWR стоит sortby, интеллектуальный оптимизатор поймет, что переупорядочивание выходных объектов снимает обычные ограничения на порядок кортежей связываний.

Q4 показывает, как выражение FLWR может походить на запрос с соединением в системе управления реляционной базой данных, а также на запрос с группировкой. Q4 похож на запрос с соединением, поскольку в нем коррелируются элементы, находящиеся в двух разных файлах — items.xml и bids.xml. Он также напоминает запрос с группировкой, поскольку ставки группируются по номеру товара, и вычисляется число ставок в каждой группе.

Арифметические операции

В XQuery обеспечиваются обычные арифметические операции: +, — , *, div и mod, а также агрегатные функции sum, avg, count, max и min, которые применяются к последовательности чисел и возвращают числовой результат. Оператор деления в XQuery называется div, чтобы его можно было отличить от слэша. Если после оператора вычитания следует имя, перед ним должен стоять пробел, который позволяет отличить его от дефиса, поскольку в XML дефис — корректный символ для имени.

Арифметические операции определяются для числовых значений. К числовым значениям относятся значения типов integer, decimal, float, double или типов, производных от них. Если типы операндов арифметической операции различны, операнды приводятся к ближайшему общему типу в соответствии с иерархией приведения integer -> decimal -> float -> double. Если операнд арифметического оператора является узлом, то автоматически извлекается его типизированное значение.

Важный частный случай — применение арифметических операций к пустым последовательностям. В XQuery пустая последовательность иногда используется для представления отсутствующей или неизвестной информации, во многом подобно тому, как неопределенное значение используется в реляционных системах. По этой причине операции +, -, *, div и mod определяются таким образом, что они возвращают пустую последовательность, если любой из операндов — пустая последовательность. Для иллюстрации этого правила предположим, что переменная $emps связана с последовательностью элементов emp, каждый из которых представляет сотрудника и содержит элементы name и salary, а также дополнительные элементы comission и bonus. Выражение в Q5 преобразует эту последовательность в последовательность элементов emp, каждый из которых содержит элементы name и pay, причем значение pay равно полной заработной плате сотрудника. Для тех сотрудников, комисионные (commission) или премия (bonus) которых не заданы ($e/commission или $e/bonus — пустая последовательность), генерируемый элемент pay будет пустым.

(Q5) Задана последовательность элементов emp. Заменить их подэлементы salary, commission и bonus на новый элемент pay, содержащий сумму значений исходных элементов, а результирующую последовательность отсортировать по убыванию значений элемента pay.

for $e in $emps

return

<emp>

{

$e/name,

<pay> {$e/salary + $e/commission+ $e/bonus} </pay>

}

</emp>

sortby (pay)

Иногда желательно определять значение по умолчанию, которое может заменять пропущенные операнды в арифметических выражениях. Ниже объясняется, как в этом случае может использоваться функция, определенная пользователем.

Операции над последовательностями

Оператор intersect порождает последовательность, в которую включены все узлы, имеющиеся в обоих операндах. Оператор except позволяет получить последовательность, содержащую все узлы, которые есть в первом операнде, но отсутствуют во втором.

Операторы union, intersect и except возвращают последовательность узлов в порядке документа и удаляют дубликаты из получившихся последовательностей с учетом индивидуальности узлов. Запрос Q6 является примером использования оператора intersect.

(Q6) Создать новый элемент с именем recent-large-bids, содержащий копии всех элементов bid документа bids.xml, которые имеют bid-amount со значением больше 1000 и bid-date со значением позже 1 января 2002 года.

<recent-large-bids>

document("bids.xml")

/*/ bid [bid-amount > 1000.00]

intersect

document("bids.xml")

/*/ bid [bid-date > date("2002-01-01")]

</recent-large-bids>

Выражения, в которых используются операции union, intersect и except, часто можно представить в другом виде. Так, запросу Q6 эквивалентен следующий запрос.

<recent-large-bids>