Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛЕКЦИИ УПРАВЛЕНИЕ ДАННЫМИ 2012.doc
Скачиваний:
5
Добавлен:
01.04.2025
Размер:
2.54 Mб
Скачать

10. Запросы к интернет-страницам

10.1. Теговая парадигма

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

Изучение XML выходит за пределы данной книги. Вкратце рассмотрим особенности теговой парадигмы, которой следует язык XML (см. Лист. 70 - Лист. 74). В теговой парадигме документ имеет иерархическую структуру вложенных друг в друга пар тегов, между которыми идут объекты документа, пример см. на Лист. 70.

Лист. 70. Теги

<b><i>Это жирный текст курсивом</i></b>

Теги могут иметь атрибуты (см Лист. 71).

Лист. 71. Теги с атрибутами

<font face = “bookman” size = “12”>Текст размером шрифта 12</font>

В документах могут использоваться сущности – любые данные, не представленные в формате языков разметки (см. Лист. 72).

Лист. 72. Сущности в XML

<!entity EmpName “Иванов”>

Здравствуйте, &EmpName!

На языке XML можно использовать пользовательские теги (см. Лист. 73), в отличие от HTML, в котором используются только стандартные теги. Эта особенность языка XML позволяет создавать хорошо структурированные документы, например, на почтовом конверте поля можно заключать в теги <от кого>, <кому> и т.п.

Лист. 73. Пользовательские теги

<sender>Петров</sender>

В языки разметки можно встраивать скриптовые языки, например, JavaScript, см. Лист. 74. Скриптовые языки, как правило, относятся к наиболее распространенным процедурным языкам с объектно-ориентированной надстройкой, например, диалекты Basic, Java. С помощью скриптов можно создавать динамические страницы, которые меняют свое оформление, проводить вычисления на клиентском компьютере или сервере. Структура такого документа представлена на Рис. 32.

Лист. 74. Встройка в теговый документ скриптового языка

<font name = “f1” size = «12»>

Текст

</font>

<script language=”javascript”>

f1.size = 14;

</script>

Рис. 32. Структура тегового документа, расширенного скриптами и запросами

Рассмотрим различия между XML и реляционными данными

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

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

  • XML-данные часто бывают «разреженными», а отсутствие информации может представляться отсутствием элемента.

10.2. Язык запросов xQuery

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

Рис. 33. Модель данных из файла items.xml

Рис. 34. Модель данных из файла bids.xml

Лист. 75. XML-документы

Items.xml

<items>

<item status = “pending”>

<itemno>100</itemno>

<seller>Рога и Копыта</seller>

<description>Суповой набор</description>

<itemno>100</itemno>

<end-date>31.04.09</end-date>

</item>

<item status = “pending”>

...

</item>

</items>

Bids.xml

<bids>

<bid>

<itemno>100</itemno>

<bidder>Мария Ивановна</bidder>

<bid-amount>100</ bid-amount >

<bid-date>31.04.09</bid-date>

</bid>

<bid>

...

</bid>

</bids>

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

Лист. 76. Пример полного путевого выражения XQuery

document("items.xml")/child::*/child::item [child::seller = "Smith"]/child::description

Лист. 77. Пример сокращенного путевого выражения XQuery

document("items.xml")/*/item[seller = "Smith"]/description

Разделение двух шагов двойным, а не одинарным слэшем означает, что второй шаг может выполнять поиск в нескольких уровнях иерархии, используя для этого ось descendants, а не одноуровневую ось child, например, Перечислить все элементы описания товаров, имеющиеся в документе items.xml (см. Лист. 78).

Лист. 78. Путевое выражение по оси «потомок»

document()//description

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

Лист. 79. Путевое выражение по оси «атрибут»

$description/../@status

Форма записи для селекции (предиката) – квадратные скобки:

  • Item [reserve-price > 1000]запись условия

  • item [5] – выбор пятого узла

  • item [reserve-price] - выбираются узлы item, у которых имеется узел-потомок reserve-price, вне зависимости от его значения.

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

Лист. 80. Конструктор элемента

<highbid status = "pending">

<itemno>4871</itemno>

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

</highbid>

Вычисления заключаются в фигурные скобки (см. Лист. 81)

Лист. 81. Конструктор элемента с вычислениями

<highbid status = "{$s}"

<itemno> {$i} </itemno>

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

</highbid>

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

Лист. 82. Вычисляемый конструктор элемента

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

Лист. 83. Конструктор атрибута

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

Конструкция FLWR (for, let, where, return) обеспечивает дополнительные способы связывания переменных. В for перечисляются объекты, для которых выполняются дальнейшие действия, как правило, эти объекты описываются запросом. В let делаются вычисления, в where прописываются условия. В return описывается то, что надо возвратить, как правило, это конструктор элемента. Например, для каждого товара, который имеет более десяти ставок, создать элемент popular-item, содержащий номер товара, описание и число ставок.

Лист. 84. Конструкция FLWR

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>

В XQuery обеспечиваются обычные арифметические операции: +, - , *, div и mod, а также агрегатные функции sum, avg, count, max и min, которые применяются к последовательности чисел и возвращают числовой результат, операции над последовательностями: union, intersect, exept, условные выражения: if then else, кванторные выражения every и some. Например, найти товары в items.xml, для которых все полученные ставки более чем вдвое превысили начальную цену. Получить копии всех таких элементов item, и поместить их в новый элемент с именем underpriced-items (см. Лист. 85).

Лист. 85. Кванторы в XQuery

<underpriced items>

for $i in document("items.xml")

where every $b in document("bids.xml")

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

satisfies $b/bid-amount

> 2 * $i/reserve-price

return $i

</underpriced-items>

Есть в Xquery и функции (см. Лист. 86)

Лист. 86. Функции

define function highbid(element $item)

returns decimal

{

max(document("bids.xml")

//bid [itemno = $item/itemno]/bid-amount)

}

highbid(document("items.xml")

//item [itemno = "1234"])

Подробнее о XQuery см. [8].

Д/З . Пример из Д/З и Д/З представьте в виде страничек XML, приведите пример конструкции FLWR с вычисляемым конструктором, условиями и путевыми выражениями разного вида (по оси «потомок» или «ребенок» и «атрибут»).

10.3. SQL и XML

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

  1. Представление результатов запроса в виде XML-страниц.

  2. Запросы к XML-страницам.

  3. Запросы к БД из XML-страниц.

Рассмотрим первые две возможности на примере Microsoft SQL Server 2000. Результирующую выборку можно представлять в формате XML с помощью ключевых слов FOR XML оператора SELECT, а также сделать запрос из документа XML с помощью оператора OPENXML.

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

Табл. 62. Ключевые слова в FOR XML

Слово

Смысл

Пример

FOR XML RAW

Результат – страница из тегов <row>. Поля запроса представлены в виде атрибутов этих тегов.

Лист. 87, Лист. 88

FOR XML AUTO

Результат – страница из тегов <Имя_таблицы>. Поля запроса представлены в виде атрибутов этих тегов.

Лист. 89, Лист. 90

FOR XML AUTO, ELEMENTS

Результат – страница из тегов <Имя_таблицы>. Поля запроса представлены в виде тегов <имя_поля>

Лист. 91, Лист. 92

FOR XML EXPLICIT

Можно формировать практически любые документы; структура результирующего XML-документа определяется непосредственно в самом запросе. Запрос может принимать очень сложный вид.

В данной книге не рассматривается

Лист. 87 Запрос с FOR XML RAW

select au_fname, au_lname, address

from authors

where au_fname like 'M%'

for xml raw

Лист. 88. Результат запроса с FOR XML RAW

<row au_fname="Marjorie" au_lname="Green" address="309 63rd St. #411" />

<row au_fname="Michael" au_lname="O'Leary" address="22 Cleveland Av. #14" />

...

Лист. 89 Запрос с FOR XML AUTO

select au_fname, au_lname, address

from authors

where au_fname like 'M%'

for xml auto

Лист. 90. Результат запроса с FOR XML AUTO

<authors au_fname="Marjorie" au_lname="Green" address="309 63rd St. #411" />

<authors au_fname="Michael" au_lname="O'Leary" address="22 Cleveland Av. #14" />

...

Лист. 91 Запрос с FOR XML AUTO, ELEMENTS

select au_fname, au_lname, address

from authors

where au_fname like 'M%'

for xml auto, elements

Лист. 92 Результат запроса с FOR XML AUTO, ELEMENTS

<authors>

<au_fname>Marjorie</au_fname>

<au_lname>Green</au_lname>

<address>309 63rd St. #411</address>

</authors>

<authors>

<au_fname>Michael</au_fname>

<au_lname>O'Leary</au_lname>

<address>22 Cleveland Av. #14</address>

</authors>

...

Функция OPENXML является аналогом OPENROWSET, OPENDATASOURCE и OPENQUERY, которые позволяют выполнять запросы из удаленных источников. Использование оператора select должно сопровождаться операторами exec sp_xml_preparedocument и exec sp_xml_removedocument, которые подготавливают и закрывают документ соответственно. Функция OPENXML используется в операторе FOR, где вместо таблицы приводится XML-документ с конструкцией Xpath, описывающей фрагмент этого документа (в квадратных скобках указывается условие отбора элементов). После функции OPENXML идет конструкция WITH, которая описывает, как элементы XML-документа преобразуются в поля таблицы. Пример XML-документа приведен на Лист. 93, запрос – на Лист. 94, результаты запроса – в Табл. 63.

Пусть у нас имеется такой XML-документ:

Лист. 93. Пример XML-страницы

<?xml version="1.0" encoding="windows-1251" ?>

<rsdn>

<forums date="09.01.03">

<forum name="WinAPI" totalposts="16688"

description="Системное программирование">

<moderators/>

<top-poster>Alex Fedotov</top-poster>

</forum>

<forum name="COM" totalposts="10116"

description="Компонентные технологии">

<moderators/>

<top-poster>Vi2</top-poster>

</forum>

<forum name="Delphi" totalposts="5001"

description="Delphi и Builder">

<moderators>

<moderator name="Sinclair"/>

<moderator name="Hacker_Delphi"/>

</moderators>

<top-poster>Sinclair</top-poster>

</forum>

<forum name="DB" totalposts="6606" description="Базы данных">

<moderators>

<moderator name="_MarlboroMan_"/>

</moderators>

<top-poster>Merle</top-poster>

</forum>

</forums>

</rsdn>

Лист. 94. SQL запрос с использованием XPath

exec sp_xml_preparedocument @hdoc out, @_xmlbody

select *

from openxml(@hdoc,'/rsdn/forums/forum')

with(totalposts varchar(100) 'attribute::totalposts')

exec sp_xml_removedocument @hdoc

Табл. 63. Результат SQL-запроса к XML-странице

totalposts

16688

10116

5001

6606

В XPath-выражениях можно использовать и сокращенную запись: «attribute::» можно заменить символом @; «self::node()» - на точку (.); «parent::node()» - на две точки (..). Другие сокращения можно найти в спецификации XPath.

Рассмотрим более сложный пример: выберем название форума, модератора и дату создания статистики для всех форумов, у которых больше 6000 сообщений (запрос см. на Лист. 95, часть запроса, использующую XPath, в сокращенной форме - Лист. 96).

Лист. 95 SQL запрос с использованием XPath и конструкции with

exec sp_xml_preparedocument @hdoc out, @_xmlbody

select

forum as 'Форум',

case when moders is null

then 'нет'

else moders

end as 'Модератор',

[date] as 'Дата создания'

from openxml(@hdoc,'/rsdn/forums/forum[attribute::totalposts > "6000"]') with

(

moders varchar(50) 'moderators/moderator/attribute::name',

forum varchar(50) 'attribute::name',

[date] varchar(50) 'parent::node()/attribute::date'

)

exec sp_xml_removedocument @hdoc

Лист. 96. SQL-запрос с использованием сокращенной записи XPath

openxml(@hdoc,'/rsdn/forums/forum[@totalposts > "6000"]') with

(

moders varchar(50) 'moderators/moderator/@name',

forum varchar(50) '@name',

[date] varchar(50) '../@date'

)

Подробнее о XML и SQL см. [9].

Д/З . Для примера БД из Д/З напишите запрос с представлением результатов в XML (вариант представления с полями в качестве элементов). Для примера XML-документа из Д/З напишите запрос на языке SQL.

Вопросы для самопроверки:

  1. Можно ли в XML создавать пользовательские теги?

  2. Чем реляционные данные отличаются от XML?

  3. Есть ли в XQuery оператор select?

  4. Какой в XQuery аналог оператора where?

  5. В каком языке есть конструкция FLWR?