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

Как описано в подразделе XML-данные, можно хранить XML-экземпляры в базе данных SQL Server. Данный подраздел описывает следующее:

  • как сформировать XML-экземпляры;
  • как преобразовать XML-экземпляры в строки;

формирование 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 Serialization from CLR Database Objects.

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

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

Использование постоянных назначений

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

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

Следующий пример вставляет строковую константу в 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/>'
ms190965.note(ru-ru,SQL.90).gifПримечание.
Для типизированного XML подлинность XML проверяется в отношении указанной схемы. Дополнительные сведения см. в разделе Типизированный и нетипизированный XML.

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

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

Сериализация XML-экземпляров

Можно использовать инструкцию CAST или CONVERT, чтобы сериализовать документы и фрагменты типа xml в любой тип данных [n][var]char или varbinary.

XML-экземпляр, приведенный к строковому типу Юникод или varbinary, по умолчанию сериализуется в UTF-16. Если значение приведено в строковый тип, не являющийся Юникодом, оно сериализуется в кодовую страницу целевого строкового типа.

См. также

Основные понятия

Типизированный и нетипизированный XML
Язык модификации XML-данных (XML DML)
Тип данных xml
Образцы приложений XML

Другие ресурсы

Методы типа данных XML

Справка и поддержка

Получение помощи по SQL Server 2005