Формирование XML-экземпляров

Как описано в подразделе Тип данных XML, XML-экземпляры можно хранить в базах данных SQL Server. В этом разделе описывается формирование XML-экземпляров.

В SQL Server сформировать XML-экземпляры можно следующими способами:

  • экземпляры строки приведения типа;

  • использование инструкции SELECT с предложением FOR XML;

  • использование назначений констант;

  • использование массовой загрузки.

Строка приведения типа и двоичные экземпляры

Любые строковые типы данных SQL Server, такие как [n][var]char, [n]text, varbinary и image, можно проанализировать в типе данных xml посредством приведения (CAST) или преобразования (CONVERT) строки к типу данных xml. Проверка нетипизированного XML подтверждает, что он сформирован правильно. Если есть схема, связанная с типом xml , также выполняется проверка. Дополнительные сведения см. в разделе Сравнение типизированного и нетипизированного XML.

XML-документы могут быть кодированы различными кодировками (например, UTF-8, UTF-16, windows-1252). Следующие правила дают сведения о том, как строка и двоичный источник взаимодействуют с кодировкой XML-документа и как ведет себя синтаксический анализатор.

Так как тип nvarchar предполагает двухбайтовую кодировку Юникод, например UTF-16 или UCS-2, синтаксический XML-анализатор сочтет значение строки как XML-документ или фрагмент в двухбайтовой кодировке Юникод. Это значит, что XML-документ должен быть закодирован в двухбайтовой кодировке Юникод, а также совместим с типом данных источника. XML-документ в кодировке UTF-16 может иметь метку порядка следования байтов (BOM) UTF-16, но в этом нет необходимости, так как контекст типа источника уточняет, что он может быть документом, закодированным только в двухбайтовой кодировке Юникод.

Содержимое строки varchar средство синтаксического анализа XML принимает за однобайтовый XML-документ или фрагмент. Так как строка источника varchar имеет связанную кодовую страницу, синтаксический анализатор будет использовать эту кодовую страницу для кодирования, если явно не была указана кодировка в самом XML. Если XML-экземпляр имеет отметку BOM или декларацию кодирования, отметка BOM или декларация должна быть согласована с кодовой страницей, иначе синтаксический анализатор выдаст ошибку.

Содержимое строки varbinary принимается за поток кодовых точек, который передается непосредственно синтаксическому XML-анализатору. Таким образом, XML-документ или фрагмент должен содержать встроенную отметку BOM или другие сведения о кодировании. Чтобы определить кодировку, синтаксическому анализатору достаточно будет просто просмотреть поток. Это значит, что XML в кодировке UTF-16 должен содержать отметку UTF-16 BOM, а экземпляр без отметки BOM и без декларации о кодировании будет интерпретироваться как UTF-8.

Если кодировка XML-документа не известна заранее, а данные вместо XML передаются как строка или двоичные данные до приведения в XML, рекомендуется рассматривать данные как varbinary. Например, при считывании данных из XML-файла с помощью функции OpenRowset() необходимо указать данные для считывания как значения varbinary(max):

select CAST(x as XML) 
from OpenRowset(BULK 'filename.xml', SINGLE_BLOB) R(x)

SQL Server внутренне представляет XML в эффективном двоичном представлении, использующем кодировку UTF-16. Пользовательская кодировка не сохранена, но она учитывается в процессе синтаксического анализа.

Приведение определяемых пользователем типов CLR

Если определяемый пользователем тип данных CLR имеет XML-сериализацию, экземпляры этого типа могут быть явно приведены к типу данных XML. Более подробные сведения о XML-сериализации определяемого пользователем типа данных CLR см. в разделе Сериализация XML из объектов базы данных CLR.

Обработка пробела в типизированном XML

В SQL Server пробел внутри содержимого элемента считается незначащим, если он появляется внутри последовательности данных, содержащей только символы пробелов, разделенных разметкой, например начальными и конечными тегами. Такой пробел не преобразуется в сущность (секции CDATA игнорируются). Данная обработка пробела отличается от пробела, описанного в спецификации XML 1.0, опубликованной консорциумом World Wide Web (W3C). Это происходит потому, что в SQL Server средство синтаксического анализа XML распознает только ограниченное число подмножеств DTD, как указано в XML 1.0. Дополнительные сведения об ограниченных подмножествах DTD, поддерживаемых в SQL Server, см. в разделе Функции CAST и CONVERT (Transact-SQL).

Синтаксический XML-анализатор отменяет незначащие пробелы при преобразовании строковых данных в XML по умолчанию, если выполняется одно из следующих условий:

  • атрибут The xml:space не определен на элементе или его родителях;

  • атрибут xml:space, действующий на элемент или на одного из его родителей, имеет значение по умолчанию.

Например:

declare @x xml
set @x = '<root>      <child/>     </root>'
select @x 

Результат:

<root><child/></root>

Однако можно изменить это поведение. Чтобы сохранить пробел для экземпляра xml DT, необходимо использовать оператор CONVERT и его дополнительный параметр style, установленный в значение 1. Например:

SELECT CONVERT(xml, N'<root>      <child/>     </root>', 1)

Если параметр style не используется или его значение установлено в 0, незначащий пробел не сохраняется для преобразования экземпляра xml DT. Дополнительные сведения о том, как использовать оператор CONVERT и его параметр style при преобразовании строковых данных в экземпляр xml DT, см. в разделе Функции CAST и CONVERT (Transact-SQL).

Пример: приведение строкового значения в типизированный XML и назначение его в столбец

Следующий пример приводит строковую переменную, содержащую фрагмент XML, в тип данных xml и затем сохраняет его в xml-столбец:

CREATE TABLE T(c1 int primary key, c2 xml)
go
DECLARE  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 

Следующая операция вставки неявно преобразовывает строку в тип xml:

INSERT INTO T VALUES (3, @s) 

Можно применить функцию cast() для явного приведения строки в тип xml:

INSERT INTO T VALUES (3, cast (@s as xml))

Или можно использовать функцию convert(), как показано ниже:

INSERT INTO T VALUES (3, convert (xml, @s)) 

Пример: преобразование строкового значения в типизированный XML и присвоение его переменной

В следующем примере строка преобразовывается в тип xml и присваивается переменной типа xml:

declare @x xml
declare  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
set @x =convert (xml, @s)
select @x

Использование инструкции SELECT с предложением FOR XML

Чтобы получить результаты в виде XML, можно использовать предложение FOR XML в инструкции SELECT. Например:

DECLARE @xmlDoc xml
SET @xmlDoc = (SELECT Column1, Column2
               FROM   Table1, Table2
               WHERE   Some condition
               FOR XML AUTO)
 ...

Инструкция SELECT возвращает текстовый XML-фрагмент, который затем анализируется в процессе присвоения переменной типа xml.

Также можно использовать директиву TYPE в предложении FOR XML, которая непосредственно возвращает результат запроса FOR XML в виде xml-данных:

Declare @xmlDoc xml
SET @xmlDoc = (SELECT ProductModelID, Name
               FROM   Production.ProductModel
               WHERE  ProductModelID=19
               FOR XML AUTO, TYPE)
SELECT @xmlDoc

Результат:

<Production.ProductModel ProductModelID="19" Name="Mountain-100" />...

В следующем примере типизированный результат xml-запроса FOR XML вставляется в xml-столбец:

CREATE TABLE T1 (c1 int, c2 xml)
go
INSERT T1(c1, c2)
SELECT 1, (SELECT ProductModelID, Name
           FROM Production.ProductModel
           WHERE ProductModelID=19
           FOR XML AUTO, TYPE)
SELECT * FROM T1
go

Дополнительные сведения о предложении FOR XML см. в разделе Создание XML с помощью предложения FOR XML.

ПримечаниеПримечание

SQL Server возвращает экземпляры типа данных xml клиенту в результате выполнения различных серверных конструкций, таких как запросы FOR XML с директивой TYPE или запросы, в которых тип данных xml используется для возвращения XML из столбцов, переменных и выходных параметров SQL. В коде клиентского приложения поставщик ADO.NET требует, чтобы информация типа данных xml отправлялась сервером в двоичном представлении. Однако в запросах FOR XML без директивы TYPE XML-данные возвращаются в строковом формате. В любом случае поставщик клиента всегда будет иметь возможность обрабатывать XML-данные в любом из форматов.

Использование назначений констант

Строковая константа может быть использована там, где ожидается экземпляр xml-типа. Это то же самое, что и неявное приведение (CAST) строки в XML. Рассмотрим пример.

DECLARE @xmlDoc xml
SET @xmlDoc = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
-- Or
SET @xmlDoc = N'<?xml version="1.0" encoding="ucs-2"?><doc/>'

Предыдущий пример неявно преобразовывает строку в тип xml и присваивает его xml-переменной.

Следующий пример вставляет строковую константу в xml-столбец:

CREATE TABLE T(c1 int primary key, c2 xml)
INSERT INTO T VALUES (3, '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>') 
ПримечаниеПримечание

Для типизированного XML подлинность XML проверяется в отношении указанной схемы. Дополнительные сведения см. в разделе Сравнение типизированного и нетипизированного XML.

Использование массовой загрузки

Улучшенная функциональность OPENROWSET (Transact-SQL) позволяет произвести массовую загрузку XML-документов в базу данных. Можно выполнить массовую загрузку XML-экземпляров из файлов в xml-столбец базы данных. Рабочие образцы см. в разделе Примеры массового импорта и экспорта XML-документов. Дополнительные сведения о загрузке XML-документов см. в разделе Загрузка XML-данных.

В данном разделе

Тема

Описание

Извлечение XML-данных

Описывает компоненты экземпляров XML, не фиксируемых при сохранении экземпляров в базах данных.