SQL Server FOR XML PATH: установить xml-объявление или инструкцию обработки "xml-stylesheet" сверху

Я хочу установить инструкцию обработки для включения таблицы стилей поверх XML:

Та же проблема была с декларацией xml (например, <?xml version="1.0" encoding="utf-8"?>)

Желаемый результат:

<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<TestPath>
  <Test>Test</Test>
  <SomeMore>SomeMore</SomeMore>
</TestPath>

Мои исследования привели меня к синтаксису тестов узлов и processing-instruction(),

это

SELECT 'type="text/xsl" href="stylesheet.xsl"' AS [processing-instruction(xml-stylesheet)]
      ,'Test' AS Test
      ,'SomeMore' AS SomeMore
FOR XML PATH('TestPath')

производит это:

<TestPath>
  <?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
  <Test>Test</Test>
  <SomeMore>SomeMore</SomeMore>
</TestPath>

Все подсказки, которые я нашел, говорят мне преобразовать XML в VARCHAR, объединить его "вручную" и преобразовать обратно в XML. Но это - как бы сказать - безобразно?

Это работает очевидно:

SELECT CAST(
'<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<TestPath>
  <Test>Test</Test>
  <SomeMore>SomeMore</SomeMore>
</TestPath>' AS XML);

Есть ли шанс решить это?

2 ответа

Решение

Есть другой способ, который потребует двух шагов, но вам не нужно обрабатывать XML как строку где-либо в процессе:

declare @result XML =
(
    SELECT 
        'Test' AS Test,
        'SomeMore' AS SomeMore
    FOR XML PATH('TestPath')
)
set @result.modify('
    insert <?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
    before /*[1]
')

Sqlfiddle Demo

Выражение XQuery передано modify() Функция сообщает SQL Server вставить узел инструкции обработки перед корневым элементом XML.

ОБНОВИТЬ:

Нашел другую альтернативу, основанную на следующей теме: Объединить два фрагмента XML в один?, Я лично предпочитаю так:

SELECT CONVERT(XML, '<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>'),
(
    SELECT 
        'Test' AS Test,
        'SomeMore' AS SomeMore
    FOR XML PATH('TestPath')
)
FOR XML PATH('')

Sqlfiddle Demo

Как оказалось, отличный ответ har07 не работает с XML-объявлением. Единственный способ, которым я мог найти, был этим:

DECLARE @ExistingXML XML=
(
    SELECT 
        'Test' AS Test,
        'SomeMore' AS SomeMore
    FOR XML PATH('TestPath'),TYPE
);

DECLARE @XmlWithDeclaration NVARCHAR(MAX)=
(
    SELECT '<?xml version="1.0" encoding="UTF-8"?>'
           +
           CAST(@ExistingXml AS NVARCHAR(MAX))
);
SELECT @XmlWithDeclaration;

Вы должны остаться в string после этого шага любое преобразование в реальный XML будет либо давать ошибку (если кодировка отличается UTF-16) или пропустит это xml-объявление.

Другие вопросы по тегам