double arrow

Запросы XPath

XPath не рассчитан на работу с реляционными данными. Чтобы использовать XPath-запросы для выборки реляционных данных, необходимо создать схему данных XDR или XSD. XDR была разработана несколько лет назад при активном участии Microsoft, т.к. в то время необходимость в схемах данных была, а, по существу, самих схем не было. С появлением XSD популярность и актуальность применения XDR начали падать.

ПРИМЕЧАНИЕ Спецификацию XSD можно найти в [5].

Схема данных выполняет две важные функции: задает структуру будущего XML-документа и определяет, какие поля и таблицы должны использоваться при выполнении запроса XPath. Такие схемы называются аннотированными схемами запросов, а атрибуты, связывающие объекты базы данных с XML-узлами – аннотациями. До выхода в свет SQLXML 2.0 можно было использовать только аннотированные схемы на основе SDR [6]. Однако сейчас лучше использовать аннотированные схемы на основе спецификации XSD [7]. Некоторую информацию по преобразованию схем из XDR в более новый формат XSD можно найти в [8].

Вот синтаксис шаблонов с использованием запросов XPath:

<your_root xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:header> <xql:param name="your_param_name"> param_value </sql:param> <xql:param name="your_param_name"> param_value </sql:param>...n </sql:header> <sql:xpath-query mapping-schema="your_schema.xml"> XPath query </sql:xpath-query></your_root>

В этом примере аннотированная схема должна находится в файле your_schema.xml. Как видно из синтаксиса, возможно создание параметризированных запросов XPath. Параметр в запросе обозначается начальным символом $.

Рассмотрим пример аннотированной схемы XDR, который будет использоваться для запросов XPath. В результирующем документе будут присутствовать имена, фамилии и адреса всех авторов:

<?xml version="1.0"?><Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:sql="urn:schemas-microsoft-com:xml-sql" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <ElementType name="address" /> <ElementType name="Authors" sql:relation="Authors"> <AttributeType name="au_fname" dt:type="string" /> <AttributeType name="au_lname" dt:type="string" /> <attribute type="au_fname"/> <attribute type="au_lname" /> <element type="address" sql:field="address"/> </ElementType></Schema>

Здесь используется аннотация relation для того, чтобы указать, с какой таблицей будет связан элемент Authors. Дочерние элементы наследуют связь с таблицей, указанной для родительского ElementType. Связывание полей таблицы или представления (view) можно выполнять явно, с использованием аннотации field. В данном примере для элементов AttributeType этого делать не нужно, т.к. отображения на соответствующие поля выполняются автоматически. Однако для дочерних элементов ElementType, которые по умолчанию связываются с таблицами, такая аннотация может быть необходима. Наиболее часто используемые аннотации приведены далее.

Теперь можно перейти к самому шаблону. Предположим, аннотированную схему вы сохранили под именем MySchema.xml.

ПРИМЕЧАНИЕ IIS различает тип XML-документа только на основе каталога, где он находится. Даже если мы не настроили специальным образом IIS на исполнение схем, их лучше хранить в одном месте. Я рекомендую хранить схемы и шаблоны в разных виртуальных каталогах. Например, template для шаблонов, schema – для схем.

Вот так выглядит шаблон, выбирающий имена, фамилии и адреса всех авторов:

<my_root xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:xpath-query mapping-schema="../Schema/MySchema.xml"> /Authors </sql:xpath-query></my_root>

Так как схемы XDR постепенно вытесняются схемами XSD, перепишем пример с использованием XSD.

ПРЕДУПРЕЖДЕНИЕ Я полтора дня потерял, когда первый раз пытался выполнить запрос XPath на XSD-схеме. ISAPI-расширение упорно выдавало ошибку «XPath: unable to find /authors in the schema». В конце концов, после непродолжительных консультаций с одним из участников форума сайта www.sql.ru, проблема была решена. Суть ее в следующем: при создании виртуального каталога я использовал оснастку mmc SQL IIS Admin.MSC, которая входит в стандартный комплект MS SQL Server’а и ничего не знает о новых возможностях SQLXML 3.0. Новая оснастка лежит в %Program Files%\SQLXML 3.0 и называется sqlisad3.msc. Ее можно запустить из меню Start->Programs->SQLXML 3.0->Configure IIS Support. Всегда пользуйтесь только ею.

Вот список основных отличий XDR от XSD[9], к которому я очень часто обращаюсь:

XDR XSD
Schema schema
ElementType element
AttributeType attribute
attribute none

С учетом этого схема будет выглядеть так:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema"> <xsd:element name="authors" sql:relation="authors"> <xsd:complexType> <xsd:attribute name="au_fname" sql:field="au_fname" /> <xsd:attribute name="au_lname" sql:field="au_lname" /> <xsd:attribute name="address" sql:field="address" /> </xsd:complexType> </xsd:element></xsd:schema>

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

<?xml version="1.0" encoding="windows-1251"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema"> <xsd:element name="Авторы" sql:relation="authors"> <xsd:complexType> <xsd:sequence> <xsd:element name="Фамилия" sql:field="au_lname"/> <xsd:element name="Адрес" sql:field="address" /> </xsd:sequence> <xsd:attribute name="Имя" sql:field="au_fname"/> </xsd:complexType> </xsd:element></xsd:schema>

Если схема находится в виртуальном каталоге, тип которого schema, вы можете выполнять XPath-запросы, непосредственно указывая их в URL. Результирующий документ может не иметь корневого элемента, поэтому не забывайте указывать параметр root.

http://server/server_pubs/schema/xsd_map_schema.xml/Авторы?root=root

Вот другие аннотации, часто используемые в схемах:

  • relationship – элемент, обозначающий связь с соответствующими друг другу первичными и внешними ключами. Используется для построения иерархических XML-документов.
  • is-constant – указывает, что соответствующий элемент не связывается с таблицей или колонкой базы данных.
  • map-field – булева переменная, принимающая значение 0 или 1. Значение 0 указывает, что соответствующий элемент не будет присутствовать в результирующем документе. С выходом SQLXML 3.0 аннотация была переименована в mapped.
  • limit-field и limit-value – предназначены для указания поля и его значения, по которым будет фильтроваться запрос к базе данных. Результат использования этих аннотаций аналогичен ограничению результирующего набора строк с помощью оператора WHERE.
  • use-cdata – указывает, что соответствующий XML-узел будет представлен в секции CDATA результирующего документа. Узел должен быть связан с полем таблицы или представления и не может применяться совместно с url-encode или ID, IDREF, IDREFS, NMTOKEN и NMTOKENS.
  • hide – булева переменная, принимающая значение 0 или 1. Указывает на то, что соответствующий XML-узел будет скрыт (значение 0) в результирующем XML-документе, однако может быть использован в запросе XPath. Не путайте её с аннотацией mapped. Различие в том, что при помощи mapped XML-узел совсем исключается из документа, так что не может быть использован в запросе XPath.

Рассмотрим пример, демонстрирующий работу некоторых из перечисленных аннотаций. В разделе FOR XML EXPLICIT был составлен иерархический список издательств и служащих, которые в них работают. Попробуем получить такой же XML-документ с помощью аннотированной схемы:

<?xml version="1.0"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema"> <xsd:annotation> <xsd:appinfo> <sql:relationship name="PubsEmployees" parent="publishers" parent-key="pub_id" child="employee" child-key="pub_id" /> </xsd:appinfo> </xsd:annotation> <xsd:element name="pubs" sql:relation="publishers"> <xsd:complexType> <xsd:sequence> <xsd:element name="employee" sql:relation="employee" sql:relationship="PubsEmployees" > <xsd:complexType> <xsd:attribute name="First_Name" sql:field="fname" type="xsd:string" /> <xsd:attribute name="Last_Name" sql:field="lname" type="xsd:string" /> <xsd:attribute name="minit" sql:field="minit" type="xsd:string" sql:hide="1" /> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="PubName" sql:field="pub_name" type="xsd:string"/> <xsd:attribute name="City" sql:field="city" type="xsd:string" sql:limit-field="pub_name" sql:limit-value="Binnet &amp; Hardley" /> </xsd:complexType> </xsd:element></xsd:schema>

Здесь использован атрибут hide для удаления XML-узла из результирующего документа, но сохранить возможность его использования в XPath-запросах. Атрибуты limit-field и limit-value ограничивают количество издательств одним – «Binnet & Hardley». Раздел xsd:annotation вынесен, однако его можно было использовать и внутри узла <xsd:element name="employee"…>. В таком случае имя элемента relationship можно было не указывать.

Примерно так можно использовать эту схему:

http://server/server_pubs/schema/schema1.xml/pubs/employee[@minit=""]?root=root

Схемы можно непосредственно указывать в шаблоне. Например:

<?xml version="1.0" encoding="windows-1251"?><my_root xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ms="urn:schemas-microsoft-com:mapping-schema" id="InLineSchema1" sql:is-mapping-schema="1"> <xsd:element name="Авторы" ms:relation="authors"> <xsd:complexType> <xsd:attribute name="Имя" ms:field="au_fname"/> <xsd:attribute name="Фамилия" ms:field="au_lname"/> <xsd:attribute name="Адрес" ms:field="address"/> </xsd:complexType> </xsd:element> </xsd:schema> <sql:xpath-query mapping-schema="#InLineSchema1"> /Авторы </sql:xpath-query></my_root>

Для того чтобы запрос XPath использовал схему, а также для сокрытия ее в результирующем документе XML, указан атрибут is-mapping-schema. Он может принимать значения 0 или 1. Кроме этого, необходимо явно сослаться на используемую схему, так как их в шаблоне может быть несколько. Это делается путем добавления атрибута id в схему и атрибута mapping-schema – в раздел самого запроса.

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

http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/443/msdncompositedoc.xml

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

К сожалению, SQL Server 2000 лишь частично поддерживает спецификацию XPath и возможности использования XPath-запросов к базе данных. Ниже приведена сводка поддерживаемых и не поддерживаемых возможностей.

Поддерживаемая функциональность XPath:

Тип Значения
Оси (axis) attribute, child, parent, and self
Операторы сравнения =,!=, <, <=, >, >=
Арифметические операторы +, -, *, div
Функции явного преобразования number(), string(), Boolean()
Булевы операторы And, or
Булевы функции true(), false(), not()

Не поддерживаемая функциональность:

Тип Значения
Оси ancestor, ancestor-or-self, descendant, descendant-or-self (//), following, following-sibling, namespace, preceding, preceding-sibling
Арифметические операторы Mod
Строковые функции string(), concat(), starts-with(), contains(), substring-before(), substring-after(), substring(), string-length(), normalize(), translate()
Булевы функции lang()
Числовые функции sum(), floor(), ceiling(), round()
Оператор объединения |

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



Сейчас читают про: