Особенность применения XPath-выражений при отображении данных состоит в том, что возможна выборка данных, расположенных практически в любой части XML-документа (относительно текущей ветки). Так, можно обратиться к подветкам текущей ветки, родительским веткам, и даже получить данные на основе выполнения некоторого условия. Если бы вместо «comment varchar(100) 'Order/text()'» было написано «comment varchar(100) 'Order'», то колонка comment первой строки содержала бы пустую строку. Она бралась бы из первого заказа (O1). Но так как текста в этом элементе нет, функция text() возвратит для него false, что приведет к поиску текста в следующем по порядку элементе Order (заказе O2). Таким образом, в сформированной записи будет находиться информация из первого заказа и комментарий из второго. Прикладного смысла это действие не имеет, но замечательно демонстрирует гибкость техники отображения.
На этом мы с вами закончим рассмотрение конструкции OPENXML. Более подробную информацию можно получить в MSDN. Спецификацию XPath можно найти в [2].
Чтобы выполнять запросы к SQL Server через HTTP, необходимо настроить соответствующим образом интернет-сервер. Делается это с помощью мастера "Configure SQL XML Support in IIS". Я не буду описывать полностью его работу, при необходимости можете обратиться к [3]. Кроме этого, настроить виртуальный каталог можно программно с помощью объекта VDirMgr. Он находится в файле sqlvdr3.dll. Для использования класса из VB нужно добавить ссылку на библиотеку типов Microsoft SQL Virtual Directory Control 1.0 Type Library.
Мастер "Configure SQL XML Support in IIS" создает виртуальный каталог, для обработки запросов к которому назначается специальное isapi-расширение: sqlisapi.dll. Эта библиотека, используя провайдер SQL OLEDB, связывается с SQL Server для отправки запросов и получения результатов. Результирующие выборки, представленные уже в формате XML, передаются обратно вызывающей стороне по HTTP. С помощью мастера вы можете указать:
Учетную запись SQL Server или Windows, под которой будут выполняться все запросы;
Компьютер, на котором расположен SQL Server и базу данных;
Подкаталоги данного виртуального каталога для хранения различных типов файлов (шаблонов, схем). Подкаталоги могут быть трех предопределенных типов: schema, template и dbobject. В подкаталоге schema хранятся XDR или XSD схемы данных, которые можно непосредственно исполнять в URL-запросе. В подкаталоге с типом template хранятся шаблоны, исполнение которых разрешено через URL-запросы. dbobject – псевдокаталог, его мы рассматривать не будем.
ПРИМЕЧАНИЕВ SQLXML 3.0 появился еще один тип подкаталогов – soap. Его рассмотрение также выходит за рамки данной статьи. |
Отдельно остановимся на настройках каталога. Вы можете:
Позволить или запретить указывать SQL-инструкции непосредственно в URL. Отмечу, что в качестве инструкций можно использовать не только запросы, но и любые другие операторы. Советую устанавливать эту опцию только для отладки, а в нормальном режиме работы выключать.
Позволить или запретить исполнение запросов, хранящихся в специальных шаблонах. Подробнее о шаблонах будет сказано далее.
Позволить или запретить использование запросов XPath;
Позволить или запретить использовать метод POST.
Рассмотрим синтаксис URL-запроса к SQL Server:
http://iisserver/vroot?sql=sqlinstruction[¶m=value[¶m=value]...n] |
Здесь:
iisserver – имя интернет-сервера;
vroot – имя виртуального каталога;
sqlinstruction – любая SQL-инструкция;
param – имя параметра. Это не параметр SQL-инструкции или хранимой процедуры, это параметр шаблона или один из следующих предопределенных параметров: contenttype, outputencoding, root и xsl;
value – значение параметра.
Итак, предположим, вы сконфигурировали виртуальный каталог для использования базы данных PUBS и назвали его server_pubs. Положим, ваш компьютер называется server. Попробуем написать первый URL-запрос:
http://server/server_pubs/?sql=select au_fname, au_lname, address from authors where au_fname like 'M%' for xml raw |
Но не все так просто. Ответ будет таким:
XML document must have a top level element. |
Первый блин, как всегда, комом! Дело в том, что XML-документ, формируемый SQL Server’ом, не имеет главного корневого элемента, без которого документ не может считаться правильно оформленным. Для указания корневого элемента нужно добавить параметр root.
http://server/server_pubs/?sql=select au_fname,au_lname,address from authors where au_fname like 'M%' for xml raw&root=my_root |
В ответ будет выдано:
Incorrect syntax near 'M'. |
Что ж, опытные пользователи, наверное, сразу бы приметили знак процента в запросе. Он является зарезервированным символом в имени URL, его код равен 25. Учитывая это, перепишем запрос так:
http://server/server_pubs/?sql=select au_fname,au_lname,address from authors where au_fname like 'M%25' for xml raw&root=my_root |
Ура! Получилось. Результат будет примерно таким же, как в самом первом примере этой статьи.
На случай, если вам нужно получить результаты в виде обычного HTML, можно создать шаблон преобразования на языке XSL и указать еще один параметр в URL – xsl. В качестве значения параметра нужно указать путь относительно выбранной вами виртуальной директории.
Составим шаблон трансформации:
<?xml version="1.0" ?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match = "*"> <xsl:apply-templates /> </xsl:template> <xsl:template match = "row"> <li> <table><tr> <td><xsl:value-of select = "attribute::au_fname" /></td> <td><xsl:value-of select = "attribute::au_lname" />.</td> <td>Address: <xsl:value-of select = "attribute::address" /></td> </tr></table> </li> </xsl:template> <xsl:template match = "/"> <html> <body> <ul> <xsl:apply-templates select = "my_root" /> </ul> </body> </html> </xsl:template></xsl:stylesheet> |
Более подробную информацию о XSL можно найти в [4].
В ответ на следующий URL-запрос вы получите преобразованный XML-документ.
http://server/server_pubs/?sql=select au_fname,au_lname,address from authors where au_fname like 'M%25' for xml raw&root = my_root&xsl = xsl_for_query.xsl |
На самом деле работа с URL-запросами интересна только первые несколько минут. Действительно, очень неудобно возиться со строкой адреса и бесконечными символами процента в ней, к тому же URL-запросы не очень хороши в смысле безопасности. Альтернативой им являются шаблоны.
Шаблоны в контексте этой статьи являются обычными XML-документами, составленными по определенным правилам. Основным их содержанием является SQL-запрос или вызов хранимой процедуры. Шаблоны также используются для запросов XPath, однако их я коснусь чуть позже. Параметры шаблона задаются в URL-строке. Если они там не указаны, берутся значения по умолчанию из соответствующих тегов <param>.
Шаблоны хранятся на сервере, поэтому в смысле безопасности их использование намного предпочтительнее, чем URL-запросов. Чтобы ISAPI-расширение, которое их обрабатывает, поняло, что вы вызываете шаблон, его нужно поместить в свой виртуальный каталог. Обычно он называется template. Настроить его можно в упоминавшемся ранее мастере "Configure SQL XML Support in IIS" на закладке Virtual Names.
Структура шаблона выглядит так:
<?xml version="1.0" ?><your_root xmlns:sql="urn:schemas-microsoft-com:xml-sql" sql:xsl="xsl file name"> <xql:header> <xql:param name="your_param_name"> param_value </sql:param> <xql:param name="your_param_name"> param_value </sql:param>...n </xql:header> <sql:query>любое SQL-выражение</sql:query></your_root> |
Для форматирования результатов исполнения шаблона может быть использована XSL-трансформация. Для этого необходимо задать атрибут xsl, значение которого есть относительный или полный путь до файла, содержащего шаблон трансформации. Атрибут xsl необязателен, как и раздел header.
Вот как будет выглядеть шаблон, основанный на изрядно уже поднадоевшем вам запросе.
<?xml version="1.0" ?><my_root xmlns:sql="urn:schemas-microsoft-com:xml-sql" sql:xsl="xsl_for_query.xsl"> <sql:query> select au_fname,au_lname,address from authors where au_fname like 'M%' for xml raw</sql:query></my_root> |
В нем используется та же схема преобразования, что и в предыдущем примере. Теперь попробуйте его вызвать (предположим, вы его сохранили под именем first_template.xml):
http://server/server_pubs/template/first_template.xml |
Результат получается довольно странным: IE представляет HTML-документ (получаемый при трансформации) в формате XML. Делает он это на вполне законных основаниях, и чтобы результат выдавался все-таки в формате HTML, нужно явно указать тип выходного потока. Это легко сделать с помощью параметра contenttype.
http://server/server_pubs/template/first_template.xml?contenttype=text/html |
Достоинства шаблонов очевидны:
Так как шаблон находится на сервере, вы полностью контролируете его содержимое;
Шаблоны намного проще в использовании;
Тело шаблона и используемая схема преобразования скрыты от пользователя;