19 августа 2019 года    
Понедельник | 18:12    
Главная
 Новости
Базы данных
Безопасность PC
Всё о компьютерах
Графика и дизайн
Интернет-технологии
Мобильные устройства
Операционные системы
Программирование
Программы
Связь
Сети
 Документация
Статьи
Самоучители
 Общение
Форум







Разделы / Интернет-технологии / XML

XQuery: что это такое

XQuery: что это такое

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

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

Язык выражений

Первое, на что следует обратить внимание, это то, что в XQuery любая конструкция - это выражение, результатом вычисления которого является некоторое значение. Программа XQuery или скрипт - это просто выражение вместе с некоторыми необязательными функциями и другими определениями. Поэтому 3+4 - это завершенная, допустимая программа XQuery, которая при вычислении равняется 7.

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

Ниже приведено условное выражение, значением котором является строка:


	if (3 < 4) then "yes!" else "no!"

Для описания локальных переменных используется выражение let:


	let $x := 5 let $y := 6 return 10*$x+$y

Это выражение равно 56.

Примитивные типы данных

Примитивные типы данных XQuery такие же, как в XML Schema:

  • числа, включая целые и числа с плавающей запятой;
  • булевы числа: true (истина) и false (ложь);
  • строки символов, например, "Hello world!". Строки являются неизменными (immutable), то есть символ в строке не может быть изменен;
  • различные типы для представления дат, времени и продолжительности.
  • несколько типов, связанных с XML. Например, QName - это часть локального имени (как template) и URL (унифицированный указатель ресурса), который используется для представления имени тега после того, как для него было установлено пространство имен (как xsl:template).

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

Величины узлов и выражения

В XQuery также есть типы данных, необходимые для представления величин XML. Для этого используются величины узлов следующих семи типов: элемент, атрибут, пространство имен, текст, комментарий, инструкция обработки и документ (корень). Эти типы очень похожи на соответствующие классы DOM: Node, Element и так далее. В некоторых реализациях XQuery используются объекты DOM для задания величин узлов, хотя в реализациях могут применять и другие представления.

Для создания и возврата узлов используются различные стандартные функции XQuery. Так, функция document читает XML-файл, указанный аргументом URL, и возвращает корневой узел документа. (Корневой элемент - это потомок корневого узла).

Новые узлы можно также создавать непосредственно в программе. Наиболее удобный способ - воспользоваться выражением конструктор элемента (element constructor), которое выглядит точно также, как регулярные данные XML:


	<p>See <a href="index.html"><i>here</i></a> for info.</p>

Чтобы поместить выражение XQuery внутрь конструкторов элементов следует воспользоваться {} (фигурными скобками). Так,


	let $i := 2 return
	let $r := <em>Value </em> return
		<p>{$r} of 10*{$i} is {10*$i}.</p>


создает


	<p><em>Value </em> of 10*2 is 20.</p>

Распространенные процессоры шаблонов, такие как JSP, ASP и PHP, позволяют вставлять выражения на языке программирования в содержимое HTML. Помимо этого XQuery разрешает помещать формы XML/ HTML внутрь выражений и использовать их в качестве значений переменных и параметров.

Величины узлов XQuery являются неизменными (после создания узла его нельзя изменить).

Последовательности

Рассмотренные атомарные величины (числа, строки и т.п.) и величины узлов (элементы, атрибуты и т.д.) известны как простые величины. Результатом вычисления выражения XQuery на самом деле является последовательность простых величин. Например,


	3,4,5


это последовательность, состоящая из 3 целых. Заметьте, что если последовательность содержит только одно значение, то она совпадает с самой величиной. Не допускается использовать вложения для последовательностей. Проиллюстрируем это - для этого воспользуемся функцией count, которая принимает один аргумент и возвращает число величин в последовательности. Тогда выражение


	let $a := 3,4
	let $b := ($a, $a)
	let $c := 99
	let $d := ()
	return (count($a), count($b), count($c), count($d))


равняется (2, 4, 1, 0), потому что $b то же самое, что и (3,4,3,4).

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


	children(<p>This is <em>very</em> cool.</p>)


возвращает последовательность из трех величин:


	"This is ", <em>very</em>, " cool."

Выражения Path и отношение к XPath

В XQuery используются path expression XPath. XQuery можно рассматривать как обобщение XPath. За исключением некоторых малоизвестных форм (в основном необычных "осевых спецификаторов") все выражения XPath являются также и выражениями XQuery. По этой причине комитет, занимающийся XQuery, также работает и над спецификацией XPath - планируется, что XQuery 1.0 и XPath 2.0 будут опубликованы одновременно.

Предположим, что корневой элемент <book> XML-файла "mybook.xml" содержится несколько элементов-потомков <chapter>:


	let $book := document("mybook.xml")/book
	return $book/chapter

Функция document возвращает корневой узел документа. Поскольку выражение /book выбирает элементы-потомки корневого узла, имя которого book, $book равняется одному корневому элементу.

$book/chapter выбирает элементы-потомки элементов верхнего уровня book, в результате чего получается последовательность узлов chapter второго уровня в документальном порядке (document order).

В следующем примере демонстрируется предикат (predicate):


	$book//para[@class="warning"]

Двойная косая черта - это синтаксис, предназначенный для выбора всех наследников (а не просто потомков) $book, причем отбираются только узлы элементов <para>, у которых значение узла атрибута по имени class равно "warning".

Необходимо отметить следующее различие между XPath и XQuery - выражения XPath могут вернуть множество узлов (node set), а такое же выражение XQuery возвращает последовательность узлов. Для обеспечения совместимости эти последовательности находятся в документальном порядке, в них удалены дубликаты - благодаря этому они эквиваленты множествам.

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

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

Выражение for позволяет организовывать цикл по элементам последовательности:


	for $x in (1 to 3) return ($x,10+$x)

Сначала вычисляется выражение, находящееся за in. Затем переменной (в данном случае $x) присваивается каждое значение из результирующей последовательности, и выражение return вычисляется для этих значений переменной. Значение всего выражения for - это упорядоченное соединение (конкатенация) всех величин выражения. В этом примере получается последовательность из шести элементов: 1,11,2,12,3,13.

Вернемся к примеру с файлом mybook.xml, предположим, что <book> содержит несколько элементов <chapter>, в каждом из которых находится элемент <title>. Приведенный ниже код создает простую страницу, на которой перечислены заголовки (title):


	<html>{
		let $book := document("mybook.xml")/book
		for $ch in $book/chapter
		return <h2>{$ch/title)</h2>
	}</html>

Термин "выражение FLWR" относится и к выражению for, и к выражению let. Аббревиатура FLWR расшифровывается как одно или несколько операторов for и/или let, необязательный оператор where и оператор result. Оператор result вычисляется только тогда, когда выражение where истинно (true).

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


	for $c in customers
	for $o in orders
	where $c.cust_id=$o.cust_id and $o.part_id="xx"
	return $c.name

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


	select customers.name
	from customers, orders
	where customers.cust_id=orders.cust_id
		and orders.part_id="xx"

Функции

Без функций, определяемых пользователем, XQuery был бы далек от языка от программирования. Определения таких функций располагаются в прологе запроса (query prologue) программы XQuery. Стоит заметить, что параметрами функции и результатами ее вычисления могут быть примитивные типы, узлы или последовательности из тех или других.

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


define function descendant-or-self ($x)
{
	$x,
	for $y in children($x)
		return descendant-or-self($y)
}
descendant-or-self(<a>X<b>Y</b></a>)

В результате, получается последовательность глубины 4:


	<a>X<b>Y</b></a>; "X"; <b>Y</b>; "Y"

Сортировка и контекст

Для сортировки последовательности используется выражение sortby. Чтобы упорядочить последовательность книг по имени автора можно сделать следующее:

$books sortby (author/name)

Выражение sortby берет входную последовательность (в данном случае $books) и одно или несколько выражений упорядочения (ordering expressions). При сортировке реализация должна сравнивать две величины из входной последовательности, чтобы определить, какая должна идти первой. Для этого вычисляется выражение(я) упорядочения в контексте величины из входной последовательности. Поэтому path expression author/name вычисляется множество раз, каждый раз относительно разной книги, используемой в качестве контекстуальной (или текущей) единицы (context (or current) item).

Path expression также используют и устанавливают этот контекст. В author/name возвращаемые потомки name - это потомки из контекстуальной единицы author.

Определение типов

XQuery - строго типизированный язык программирования. Как Java и C#, XQuery - это смесь статического (проверка совместимости типов во время компиляции) и динамического контроля типов (тестирование типов во время выполнения). Однако, типы в XQuery отличаются от классов, присущих объектно-ориентрованному программированию. Взамен XQuery включает типы, которые соответствуют модели данных XQuery, и позволяет импортировать типы из XML Schema.


	if ($child instance of element section)
	then process-section($child)
	else ( ) {--nothing--}

В этом фрагменте кода функция process-section вызывается, если значением $child является элемент, имя тега которого section. В XQuery для сопоставления величины с набором типов есть удобная сокращенная форма (typeswitch). В следующем примере показывается, как преобразовывать один набор имен тегов в другой набор:


define function convert($x) {
	typeswitch ($x)
		case element para return <p>{process-children($x)}</p>
		case element emph  return <em>{process-children($x)}</em>
		default return process-children($x)
}
define function process-children($x) {
	for $ch in children($x) return convert($ch)
XQuery: что это такое
Лента новостей


2006 (c) Copyright Hardline.ru