SQL Server 2008 - добавление XML-декларации в XML-вывод

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

 SELECT (
   SELECT CONVERT(VARCHAR(10),GETDATE(),103)
   FOR XML PATH('DataVersion'), 
     TYPE
   ),
   (  
   SELECT CoNum,
     CoName,
     CONVERT(VARCHAR(10),AccountToDate,103) 'DLA',
     LAFileNet
   FROM @XMLOutput  
   FOR XML PATH('Company'),
     TYPE  
   )
 FOR XML PATH(''),
   ROOT('Companies')

Что создает нижний вывод

<Companies>
  <DataVersion>15/11/2010</DataVersion>
  <Company>
    <CoNum>111</CoNum>
    <CoName>ABCLmt</CoName>
    <DLA>12/12/2010</DLA>
    <LAFileNet>1234</LAFileNet>
  </Company>
  <Company>
    <CoNum>222</CoNum>
    <CoName>DEFLmt</CoName>
    <DLA>12/12/2007</DLA>
    <LAFileNet>5678</LAFileNet>
  </Company>
</Companies>

С чем я боюсь, как добавить объявление XML <?xml version="1.0" encoding="ISO-8859-1" ?> в начало вывода?

Обновление 1: Я был бы прав, думая, что мне нужно создать XML-схему на SQL-сервере, чтобы определить выход xsl:. Затем назначьте вывод этой схеме?

Обновление 2: с тех пор нашли эти ссылки http://forums.asp.net/t/1455808.aspx - Отметьте комментарий от Jian Kang. Также http://www.devnewsgroups.net/group/microsoft.public.sqlserver.xml/topic60022.aspx

Ответ 1

TL; DR

Объединить это: <?xml version="1.0" encoding="windows-1252" ?> с вашим XML, преобразованным в varchar (max).

Подробнее

Я согласен с j0N45, что схема ничего не изменит. Как ответ, на который он ссылается, указывает:

Вам нужно добавить его вручную.

Я привел несколько примеров кода для этого в другом ответе. В принципе, вы CONVERT XML в varchar или nvarchar, а затем объединяете его с объявлением XML, например <?xml version="1.0" encoding="windows-1252" ?>.

Однако важно выбрать правильную кодировку. SQL Server создает строки, отличные от Unicode, в соответствии со своими настройками сортировки. По умолчанию это будет определяться настройками сортировки базы данных, которые вы можете определить с помощью этого SQL:

SELECT DATABASEPROPERTYEX('ExampleDatabaseName', 'Collation');

Общая сортировка по умолчанию - это "SQL_Latin1_General_CP1_CI_AS", которая имеет кодовую страницу 1252. Вы можете получить кодовую страницу с этим SQL:

SELECT COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS 'CodePage';

Для кодовой страницы 1252 вы должны использовать имя кодировки " windows-1252". Использование "ISO-8859-1" является неточным. Вы можете проверить это, используя символ "bullet": •. Он имеет значение кодовой точки Unicode 8226 (Hex 2022). Вы можете генерировать символ в SQL надежно, независимо от сортировки, используя этот код:

SELECT NCHAR(8226);

Он также имеет кодовую точку 149 на кодовой странице окна-1252, так что если вы используете общую сортировку по умолчанию "SQL_Latin1_General_CP1_CI_AS", то вы также можете ее создать, используя:

SELECT CHAR(149);

Однако CHAR (149) не будет пулей во всех сопоставлениях. Например, если вы попробуете это:

SELECT CONVERT(char(1),char(149)) COLLATE Chinese_Hong_Kong_Stroke_90_BIN;

Вы не получаете пулю вообще.

Кодовая страница "ISO-8859-1" - это Windows-28591. Ни одна из коллизий SQL Server (в любом случае в 2005 году) не использует эту кодовую страницу. Вы можете получить полный список кодовых страниц, используя:

SELECT [Name], [Description], [CodePage] = COLLATIONPROPERTY([Name], 'CodePage')
FROM ::fn_helpcollations()
ORDER BY [CodePage] DESC;

Вы также можете убедиться, что "ISO-8859-1" является неправильным выбором, пытаясь использовать его в самом SQL. Следующий SQL:

SELECT CONVERT(xml,'<?xml version="1.0" encoding="ISO-8859-1"?><test>•</test>');

Производит XML, который не содержит пулю. В самом деле, он не будет выдавать символ, потому что ISO-8859-1 не имеет символа, определенного для кодовой точки 149.

SQL Server обрабатывает строки Unicode по-разному. С строками Unicode (nvarchar), "нет необходимости в разных кодовых страницах для обработки разных наборов символов" . Однако SQL Server НЕ использует кодировку "UTF-8". Если вы попытаетесь использовать его внутри самого SQL:

SELECT CONVERT(xml,N'<?xml version="1.0" encoding="UTF-8"?><test>•</test>');

Вы получите сообщение об ошибке:

Msg 9402, уровень 16, состояние 1, строка 1 Разбор XML: строка 1, символ 38, невозможно переключить кодировку

Скорее, SQL использует кодировку "UCS-2", поэтому это будет работать:

SELECT CONVERT(xml,N'<?xml version="1.0" encoding="UCS-2"?><test>•</test>');