Примерно так можно использовать эту схему:
| 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. Его можно бесплатно скачать по адресу
К сожалению, 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() |
| Оператор объединения | | |
Вы можете использовать неограниченное количество простых запросов (query) и запросов XPath (XPath-query) в одном шаблоне, а также использовать их вперемешку.
В качестве простых запросов (query) могут выступать любые SQL-инструкции. Шаблоны могут быть использованы для изменения данных, хотя это и не лучшее решение. Другие методы изменения данных рассматриваются в разделе Апдейтаграммы и XML Bulk Load.
| Пространство имен | Назначение |
| urn:schemas-microsoft-com:xml-sql | Шаблоны и Аннотации XDR |
| urn:schemas-microsoft-com:xml-data | Схемы XDR |
| http://www.w3.org/2001/XMLSchema | Схемы XSD |
| urn:schemas-microsoft-com:mapping-schema | Аннотации XSD |
Исторически самой первой и самой известной возможностью работы с XML-документами в ADO было сохранение объекта Recordset в формате XML. До этого вы могли сохранять Recordset’ы только в бинарном формате adPersistADTG. Он использовался для передачи наборов строк посредством RDS (Remote Data Services). Работу с обоими форматами поддерживает OLE DB Persistence Provider. Кроме сохранения, можно также загружать (восстанавливать) объект Recordset из файлов. Сохранение и последующая загрузка рекордсета из файла в формате XML дали возможность использования XML-документов в качестве баз данных.
OLE DB Persistence Provider жестко задает формат результирующего XML-документа: для описания структуры и типов узлов всегда используется XDR, данные всегда помещаются в секцию data, а строки представляются элементом row. Названия и значения полей – соответствующие названия и значения атрибутов элемента row. Нет никакой возможности изменить этот формат, если он по каким-либо причинам вас не устраивает. Можно, конечно, написать шаблон трансформации на XSLT, но это уже дополнительные сложности.
С выходом ADO 2.5 появилась возможность сохранять рекордсет в IStream. Трудно переоценить все достоинства этого нововведения: рекордсет теперь можно было сохранять в объект DOMDocument, трансформировать XML-документ с помощью метода transformNode, добавлять свои элементы и атрибуты, и многое другое. Кроме этого, вы могли сохранять рекордсет в поток Response объектной модели ASP, причем как в формате adPersistADTG, так и в формате adPersistXML. В новой ADO 2.5 появился собственный объект Stream (естественно, поддерживающий интерфейс IStream). С его помощью вы могли сохранять и загружать данные из файла на диске в бинарном формате (LoadFromFile и SaveToFile), загружать и сохранять данные в виде текста (ReadText и WriteText) и выполнять другие не реляционные операции. Но довольно истории, давайте перейдем к примерам.
Сохранение и загрузка из файла в формате XML
Не мудрствуя лукаво, возьму запрос из самого первого примера этой статьи. Вот полный исходный текст vbs-скрипта:
| Const adopenStatic = 3Const adLockReadOnly = 1Const adCmdText = 1Const adPersistXML = 1Dim rsSet rs = CreateObject("ADODB.Recordset")rs.Open "select au_fname,au_lname,address from authors where au_fname like 'M%'", _ "Provider=sqloledb;Data Source=server;Initial Catalog=pubs;" & _ "User Id=user;Password=password;", adopenStatic, adLockReadOnly, adCmdTextrs.Save "c:\myrs.xml", adPersistXML |
Следующий пример демонстрирует загрузку XML-документа в объект Recordset:
| Const adopenStatic = 3Const adLockReadOnly = 1Const adCmdFile = 256Dim rsSet rs = CreateObject("ADODB.Recordset")rs.Open "c:\myrs.xml", "Provider=MSPersist;", adopenStatic, adLockReadOnly, adCmdFile |
Трансформация с помощью DOMDocument
В этом примере создается ASP-страница, при обращении к которой из базы будет выбран Recordset и сохранен в объект DOMDocument. Далее к документу будет применен шаблон трансформации, и результирующий HTML будет передан клиенту. Результат будет точно таким же, как в примере с трансформацией в разделе «URL-запросы». Код ASP:
| <%' Define some constant for ADO.Const adopenStatic = 3Const adLockReadOnly = 1Const adCmdText = 1Const adPersistXML = 1' Creating objectsDim rs,dom,stylesheetSet dom = Server.CreateObject("MSXML2.DOMDocument")Set stylesheet = Server.CreateObject("MSXML2.DOMDocument")Set rs = Server.CreateObject("ADODB.Recordset")' Open recordsetrs.Open "select au_fname,au_lname,address from authors where au_fname like 'M%'", _ "Provider=sqloledb;Data Source=server;Initial Catalog=pubs;" & _ "User Id=user;Password=password;", adopenStatic, adLockReadOnly, adCmdText' Save recordset to DOMDocumentrs.Save dom,adPersistXML' Loading stylesheetstylesheet.async = falsestylesheet.load "C:\Inetpub\wwwroot\server_pubs\format_for_ado.xsl"' Perform transformationResponse.Write dom.transformNode(stylesheet)' CleanupSet dom = nothingSet stylesheet = nothingSet rs = nothing%> |
Шаблон трансформации практически не изменился:
| <?xml version="1.0" ?><xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" version="1.0"> <xsl:template match = "*"> <xsl:apply-templates /> </xsl:template> <xsl:template match = "z:row"> <li> <table><tr> <td><xsl:value-of select = "@au_fname" /></td> <td><xsl:value-of select = "@au_lname" />.</td> <td>Address: <xsl:value-of select = "@address" /></td> </tr></table> </li> </xsl:template> <xsl:template match = "/"> <html> <body> <ul> <xsl:apply-templates select = "xml/rs:data" /> </ul> </body> </html> </xsl:template></xsl:stylesheet> |
Выдача Recordset’а в формате XML непосредственно в поток Response
Рассмотрим совсем легкий пример выдачи рекордсета в объект Response модели ASP.
| <%' Should specify thisResponse.ContentType = "text/xml"' Define some constant for ADO.Const adopenStatic = 3Const adLockReadOnly = 1Const adCmdText = 1Const adPersistXML = 1Dim rsSet rs = Server.CreateObject("ADODB.Recordset")' Open recordsetrs.Open "select au_fname,au_lname,address from authors where au_fname like 'M%'", _ "Provider=sqloledb;Data Source=server;Initial Catalog=pubs;" & _ "User Id=user;Password=password;", adopenStatic, adLockReadOnly, adCmdText' Save recordset to Response streamrs.Save Response,adPersistXMLSet rs = nothing%> |
Этот чрезвычайно простой пример демонстрирует богатые возможности манипулирования результирующим набором строк на клиенте. Рассмотрим использование объекта RDS.DataControl.
| ПРИМЕЧАНИЕВозможно, эффективнее для RDS использовать формат adPersistADTG, однако XML для этого также прекрасно подходит. |
Пример взят из MSDN и слегка модифицирован:
| <HTML><HEAD><TITLE>Пример ADO Recordset Persistence</TITLE></HEAD><BODY><OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="RDC1" <PARAM NAME="URL" VALUE="http://yourserver/XMLPersist/XMLResponse.asp"></OBJECT><TABLE DATASRC="#RDC1"> <TR> <TD><SPAN DATAFLD="au_fname"></SPAN></TD> <TD><SPAN DATAFLD="au_lname"></SPAN></TD> <TD><SPAN DATAFLD="address"></SPAN></TD></TR></TABLE></BODY></HTML> |
А вот как создать на клиенте точную копию отправленного рекордсета (код на vbs):
| Dim rsSet rs = CreateObject("ADODB.Recordset")rs.Open "http://server/server_dir/sql2xml.asp" |
В этой версии библиотеки появилась возможность выполнять с помощью объекта Command не только SQL-запросы, но и XML-шаблоны и запросы XPath. Для этого было введено новое свойство Dialect. Далее приведены все известные на сегодняшний момент значения этого свойства [10].