Как добавить xml-кодировку <? Xml version = "1.0" encoding = "UTF-8"?> В xml Вывод в SQL Server

Вероятно, дубликат без ответа. SQL Server 2008 - добавление XML-декларации в XML-вывод

Пожалуйста, дайте мне знать, если это возможно. Я читал в некоторых блогах

http://forums.asp.net/t/1455808.aspx/1

http://www.devnewsgroups.net/group/microsoft.public.sqlserver.xml/topic60022.aspx

Но я не мог понять, почему я не могу этого сделать.

Ответ 1

Вы должны добавить его вручную. SQL Server всегда хранит xml внутри как ucs-2, поэтому SQL не может генерировать заголовок кодировки utf-8

См. "Ограничения типа данных xml" на MSDN

Объявление XML PI, например, <?xml version='1.0'?>, не сохраняется при хранении данных XML в экземпляре типа данных xml. Это по дизайну. Объявление XML (<?xml ... ?>) и его атрибуты (версия/кодирование/автономное) теряются после преобразования данных в тип xml. Декларация XML рассматривается как директива для синтаксического анализа XML. XML-данные хранятся внутри ucs-2.

Ответ 2

Когда я прочитал этот пост, я подумал, что это "конец строки"... нет решения... Я почти отказался от подхода... но на самом деле есть способ обойти это ограничение на преобразование XML в varchar (max), а затем добавление объявления в начало строки. Следующая публикация показывает, как:

Использование SQL Server "FOR XML" : Преобразование типа данных результата в текст /varchar/string независимо?

Простой пример будет выглядеть примерно так:

SELECT 'MY DATA' As MyColumn INTO #MyTable 
SELECT '<?xml version="1.0" encoding="UTF-8"?>' + 
CAST((SELECT MyColumn FROM #MyTable FOR XML PATH('')) AS VARCHAR(MAX)) AS XmlData
DROP TABLE #MyTable 

Выход:

<?xml version="1.0" encoding="UTF-8"?>
<MyColumn>MY DATA</MyColumn>

Ответ 3

Я работаю над этим вопросом в последние дни, и, хотя могут быть лучшие решения, я очень доволен этим bash script:

iconv -f UCS-2 -t UTF-8 products.xml > products_utf8.xml
echo "<?xml version='1.0'?>\n<products>\n$(cat products_utf8.xml)\n</products>" > products_utf8_final.xml

В принципе, этот script получит файл, созданный из ужасного программного обеспечения bcp, который генерирует неполные и недопустимые данные XML, преобразует его из формата UCS-2 в UTF-8 (первая строка) и добавляет в начале и конец файла, что ему нужно (вторая строка script) будет действительной и полной.

Это работает для меня. script Я использовал для генерации XML файла с BCP:

bcp.exe "select * from dat1.dbo.Products FOR XML AUTO,ELEMENTS" queryout "C:\products.xml" -T -w -r -S .\SQLEXPRESS

Ответ 4

Принятый ответ "добавить его вручную", хотя и технически корректен, является неполным и, следовательно, вводит в заблуждение. Просто добавив объявление XML с любой "кодировкой", которую вы хотите, не изменит фактическую кодировку строки. Иногда это нормально. Если вы укажете "UTF-8" и преобразуете данные XML в VARCHAR, то до тех пор, пока все символы являются стандартными символами ASCII (значения 1 - 127), тогда обязательно, это UTF-8 (по крайней мере, нет заметной разницы). НО, если есть символы со значениями 128 или выше, то у вас нет XML-документа с кодировкой UTF-8. И если вы преобразуете данные XML в NVARCHAR, тогда у вас есть кодированный UTF-16 документ, независимо от того, что вы указали вручную в объявлении XML. Вы должны указывать только кодировку, если используется фактическая кодировка.

И до SQL Server 2019 (в настоящее время в бета-версии на CTP 2.1) невозможно было заставить кодирование быть UTF-8 в SQL Server, по крайней мере, не без использования SQLCLR. Но в SQL Server 2019 теперь вы можете преобразовать XML в фактический UTF-8:

DECLARE @XML XML;
SET @XML = N'<test attr="&#x1F60E;"/>';
SELECT @XML,
       CONVERT(VARBINARY(100), CONVERT(NVARCHAR(MAX), @XML)), -- UTF-16 / UCS-2
       CONVERT(VARBINARY(100),
               CONVERT(VARCHAR(MAX),
                       CONVERT(NVARCHAR(MAX), @XML) COLLATE Latin1_General_100_CI_AS_SC_UTF8)
              ); -- UTF-8

Это возвращает:

Column 1: <test attr="😎" />
Column 2: 0x3C007400650073007400200061007400740072003D0022003DD80EDE22002F003E00
Column 3: 0x3C7465737420617474723D223F3F222F3E

Поскольку многие люди не будут на SQL Server 2019 еще некоторое время, это возможно через SQLCLR. Вы можете использовать классы.NET Xml (например, XmlWriter) для экспорта с различными параметрами. Фактически, я создал библиотеку SQLCLR функций, SQL #, которая включает в себя такую функцию: XML_SaveToFile. Функция XML_SaveToFile позволяет указать любую допустимую кодировку, и она установит это в объявлении XML и гарантирует, что файл будет сохранен с этой кодировкой. У него также есть опции для отступов, новых строк и т.д. Просто FYI: хотя в бесплатной версии доступно множество функций, XML_SaveToFile доступен только в полной версии (оплачивается).