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-объявление.