Поделиться через


Форматирование XML на стороне клиента и сервера (SQLXML 4.0)

В этом разделе описываются общие различия между форматированием XML на стороне клиента и сервера в SQLXML.

Несколько запросов набора строк, не поддерживаемых в форматировании на стороне клиента

Запросы, создающие несколько наборов строк, не поддерживаются при использовании форматирования XML на стороне клиента. Например, предположим, что у вас есть виртуальный каталог, в котором задано форматирование на стороне клиента. Рассмотрим этот пример шаблона, который содержит две инструкции SELECT в блоке <sql:query> :

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query>  
     SELECT FirstName FROM Person.Contact FOR XML Nested;   
     SELECT LastName FROM Person.Contact FOR XML Nested    
  </sql:query>  
</ROOT>  

Этот шаблон можно выполнить в коде приложения и возвращается ошибка, так как форматирование XML на стороне клиента не поддерживает форматирование нескольких наборов строк. Если указать запросы в двух отдельных <блоках sql:query> , вы получите нужные результаты.

Сопоставление меток времени по-разному в клиенте и на стороне сервера

В форматировании XML на стороне сервера столбец timestamp типа базы данных сопоставляется с типом XDR i8 (если параметр XMLDATA указан в запросе).

В форматировании XML на стороне клиента столбец timestamp типа базы данных сопоставляется с uri типом XDR или bin.base64 типом XDR (в зависимости от того, указан ли в запросе параметр двоичного файла base64). Тип bin.base64 XDR полезен, если вы используете функции updategram и bulkload, так как этот тип преобразуется в тип SQL Server timestamp . Таким образом, операция вставки, обновления или удаления завершается успешно.

Глубокие VARIANT используются в форматировании на стороне сервера

В форматировании XML на стороне сервера используются глубокие типы типа VARIANT. При использовании форматирования XML на стороне клиента варианты преобразуются в строку Юникода, а подтипы VARIANT не используются.

Вложенный режим и режим AUTO

Режим NESTED на стороне клиента FOR XML аналогичен режиму AUTO на стороне сервера FOR XML со следующими исключениями:

При запросе представлений с помощью режима AUTO на стороне сервера имя представления возвращается в качестве имени элемента в результирующем XML.

Например, предположим, что в таблице Person.Contact в Базе данных AdventureWorksdatabase создается следующее представление:

CREATE VIEW ContactView AS (SELECT ContactID as CID,  
                               FirstName  as FName,  
                               LastName  as LName  
                        FROM Person.Contact)  

Следующий шаблон задает запрос к представлению ContactView, а также задает форматирование XML на стороне сервера:

 <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query client-side-xml="0">  
    SELECT *  
    FROM   ContactView  
    FOR XML AUTO  
  </sql:query>  
</ROOT>  

При выполнении шаблона возвращается следующий XML-код. (Показаны только частичные результаты.) Обратите внимание, что имена элементов — это имена представлений, для которых выполняется запрос.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <ContactView CID="1" FName="Gustavo" LName="Achong" />   
  <ContactView CID="2" FName="Catherine" LName="Abel" />   
...  
</ROOT>  

При указании форматирования XML на стороне клиента с помощью соответствующего режима NESTED имена базовой таблицы возвращаются в виде имен элементов в результирующем XML. Например, следующий измененный шаблон выполняет ту же инструкцию SELECT, но форматирование XML выполняется на стороне клиента (то есть в шаблоне задано значение true).

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query client-side-xml="1">  
    SELECT *  
    FROM   ContactView  
    FOR XML NESTED  
  </sql:query>  
</ROOT>  

При выполнении этого шаблона создается следующий XML-код. Обратите внимание, что имя элемента — это имя базовой таблицы в данном случае.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <Person.Contact CID="1" FName="Gustavo" LName="Achong" />   
  <Person.Contact CID="2" FName="Catherine" LName="Abel" />   
...  
</ROOT>  

При использовании режима AUTO на стороне сервера FOR XML псевдонимы таблицы, указанные в запросе, возвращаются в виде имен элементов в результирующем XML.

Например, рассмотрим этот шаблон:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query client-side-xml="0">  
    SELECT FirstName as fname,  
           LastName as lname  
    FROM   Person.Contact C  
    FOR XML AUTO  
  </sql:query>  
</ROOT>  

При выполнении шаблона создается следующий XML-код:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <C fname="Gustavo" lname="Achong" />   
  <C fname="Catherine" lname="Abel" />   
...  
</ROOT>   

При использовании режима NESTED на стороне клиента FOR XML имена таблиц возвращаются в виде имен элементов в результирующем XML. (Псевдонимы таблиц, указанные в запросе, не используются.) Например, рассмотрим этот шаблон:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query client-side-xml="1">  
    SELECT FirstName as fname,  
           LastName as lname  
    FROM   Person.Contact C  
    FOR XML NESTED  
  </sql:query>  
</ROOT>  

При выполнении шаблона создается следующий XML-код:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <Person.Contact fname="Gustavo" lname="Achong" />   
  <Person.Contact fname="Catherine" lname="Abel" />   
...  
</ROOT>  

Если у вас есть запрос, возвращающий столбцы в виде запросов dbobject, нельзя использовать псевдонимы для этих столбцов.

Например, рассмотрим следующий шаблон, который выполняет запрос, который возвращает идентификатор сотрудника и фотографию.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
<sql:query client-side-xml="1">  
   SELECT ProductPhotoID, LargePhoto as P  
   FROM   Production.ProductPhoto  
   WHERE  ProductPhotoID=5  
   FOR XML NESTED, elements  
</sql:query>  
</ROOT>  

При выполнении этого шаблона столбец Photo возвращается в виде запроса dbobject. В этом запросе @P dbobject ссылается на имя столбца, которое не существует.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <Production.ProductPhoto>  
    <ProductPhotoID>5</ProductPhotoID>  
    <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID='5']/@P</LargePhoto>  
  </Production.ProductPhoto>  
</ROOT>  

Если форматирование XML выполняется на сервере (client-side-xml="0"), можно использовать псевдоним для столбцов, возвращающих запросы dbobject, в которых возвращаются фактические имена таблиц и столбцов (даже если у вас есть псевдонимы). Например, следующий шаблон выполняет запрос, и xml-форматирование выполняется на сервере (параметр client-side-xml не указан, и параметр run On Client не выбран для виртуального корневого каталога). Запрос также задает режим AUTO (а не клиентский режим NESTED).

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
<sql:query   
   SELECT ProductPhotoID, LargePhoto as P  
   FROM   Production.ProductPhoto  
   WHERE  ProductPhotoID=5  
   FOR XML AUTO, elements  
</sql:query>  
</ROOT>  

При выполнении этого шаблона возвращается следующий XML-документ (обратите внимание, что псевдонимы не используются в запросе dbobject для столбца LargePhoto):

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <Production.ProductPhoto>  
    <ProductPhotoID>5</ProductPhotoID>  
    <LargePhoto>dbobject/Production.ProductPhoto[@ProductPhotoID='5']/@LargePhoto</LargePhoto>  
  </Production.ProductPhoto>  
</ROOT>  

Клиентская и серверная часть XPath

Клиентская XPath и серверная XPath работают одинаково, за исключением следующих различий:

  • Преобразования данных, применяемые при использовании клиентских запросов XPath, отличаются от тех, которые применяются при использовании запросов XPath на стороне сервера. На стороне клиента XPath вместо режима CONVERT 126 используется CAST.

  • При указании client-side-xml="0" (false) в шаблоне требуется форматирование XML на стороне сервера. Поэтому нельзя указать FOR XML NESTED, так как сервер не распознает параметр NESTED. Это приводит к ошибке. Необходимо использовать режимы AUTO, RAW или EXPLICIT, которые распознает сервер.

  • При указании клиентского xml="1" (true) в шаблоне требуется форматирование XML на стороне клиента. В этом случае можно указать FOR XML NESTED. При указании FOR XML AUTO форматирование XML происходит на стороне сервера, хотя в шаблоне указывается значение "1" на стороне клиента .

См. также

Рекомендации по безопасности XML (SQLXML 4.0)
Форматирование XML на стороне клиента (SQLXML 4.0)
Форматирование XML на стороне сервера (SQLXML 4.0)