TSQL - openxml使用编码值解码xml元素

时间:2014-04-04 00:03:04

标签: xml sql-server-2008 tsql

是否有办法阻止SQL Server 2008解码XML元素值(如果它们恰好被编码)?

例如,我有以下查询:

declare @T nvarchar(max)
SET @T = '<node><val>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</val></node>'

declare @doc nvarchar(max), @idoc int
SET @doc = @T

exec sp_xml_preparedocument @idoc output, @doc;

select * from openxml (@idoc, '//*')

exec sp_xml_removedocument @idoc;

执行后,<val>的值最终为

<?xml version="1.0" encoding="UTF-8"?>

它应该保持为

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

2 个答案:

答案 0 :(得分:0)

这是正确的行为。通过使用&lt;之类的实体,您只需将这些值编码为XML节点中的存储。您正在存储<,但将其表示为&lt;,以免混淆XML解析器。当它输出时,默认情况下会被解码。

如果您想要输出中的编码值,则必须进行双重编码:

declare @T nvarchar(max)
SET @T = '<node><val>&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;</val></node>'

declare @doc nvarchar(max), @idoc int
SET @doc = @T

exec sp_xml_preparedocument @idoc output, @doc;

select * from openxml (@idoc, '//*')

exec sp_xml_removedocument @idoc;

或者您可以将编码的xml值包装为CDATA block

declare @T nvarchar(max)
SET @T = '<node><val><![CDATA[&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;]]></val></node>'

declare @doc nvarchar(max), @idoc int
SET @doc = @T

exec sp_xml_preparedocument @idoc output, @doc;

select * from openxml (@idoc, '//*')

exec sp_xml_removedocument @idoc;

答案 1 :(得分:0)

您可以使用XML数据类型并将query()的结果转换为nvarchar(max)

declare @X xml 
set @X = '<node><val>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</val></node>'
select cast(@X.query('/node/val/text()') as nvarchar(max))

结果

&lt;?xml version="1.0" encoding="UTF-8"?&gt;