SQL Server FOR XML PATH: Set xml-declaration or processing instruction "xml-stylesheet" on top
SQL Server FOR XML PATH: Set xml-declaration or processing instruction "xml-stylesheet" on top
我想设置一个处理指令以在 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>
我的研究让我接触到了 node test 语法和 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,将其连接 "manually" 并将其转换回 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]
')
传递给modify()
函数的XQuery 表达式告诉SQL 服务器在XML 的根元素之前插入处理指令节点。
更新:
根据以下线程找到另一个替代方案:Merge the two xml fragments into one?。我个人更喜欢这种方式:
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('')
当它出来时,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
行,任何转换到real XML都会报错(当编码是其他然后 UTF-16
) 或将省略此 xml-声明。
我想设置一个处理指令以在 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>
我的研究让我接触到了 node test 语法和 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,将其连接 "manually" 并将其转换回 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]
')
传递给modify()
函数的XQuery 表达式告诉SQL 服务器在XML 的根元素之前插入处理指令节点。
更新:
根据以下线程找到另一个替代方案:Merge the two xml fragments into one?。我个人更喜欢这种方式:
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('')
当它出来时,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
行,任何转换到real XML都会报错(当编码是其他然后 UTF-16
) 或将省略此 xml-声明。