SQL Server for xml 路径:在顶部设置 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);

有机会解决这个问题吗?

还有另一种方法,它需要两个步骤,但不需要在过程中的任何地方将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

传递给modify()函数的XQuery表达式告诉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 N'<?xml version="1.0" encoding="UTF-8"?>'
           +
           CAST(@ExistingXml AS NVARCHAR(MAX))
);
SELECT @XmlWithDeclaration;

在此步骤之后,您必须停留在string行中,任何到真实XML的转换都将产生错误(当编码不是UTF-16时),或者将省略此XML声明。

最新更新