SQL 服务器 xml 带有 CDATA

SQL SERVER xml with CDATA

我的数据库中有一个 table,其中有一列包含 xml。列类型为 nvarchar(max)。 xml就是这样组成的

<root>
  <child>....</child>
  .
  .
  <special>
   <event><![CDATA[text->text]]></event>
   <event><![CDATA[text->text]]></event>
  ...
  </special>
</root>

我没有创建数据库,我无法更改信息存储在其中的方式,但我可以使用 select 检索它。对于我使用的提取 select cast(替换(xml,'utf-8','utf-16')as xml) 来自 table

除了cdata,查询输出的内容是:text -> text

有没有办法同时检索 CDATA 标签?

嗯,据我所知,这在正常情况下是不可能的...

CDATA 部分只有一个原因:包括 无效字符 XML 适合懒人...

CDATA 根本没有被视为需要,因此正常的 XML 方法并不真正支持。或者换句话说:内容被正确转义的方式得到支持。实际上 CDATA 内正确转义的内容和未转义的内容没有区别! (好吧,有一些细微差别,比如在 中包括 ]]> 一个 CDATA 部分和一些更小的专业...)

最大的问题是:为什么?

你之后想用这个做什么?

试试这个。包含的文本按原样给出:

DECLARE @xml XML = 
'<root>
  <special>
   <event><![CDATA[text->text]]></event>
   <event><![CDATA[text->text]]></event>
  </special>
</root>'

SELECT t.c.query('text()')
FROM @xml.nodes('/root/special/event') t(c);

所以:请解释更多细节:你真正想要什么?

如果你真的只需要包装 CDATA 你可以使用这个:

SELECT '<![CDATA[' + t.c.value('.','varchar(max)') + ']]>'
FROM @xml.nodes('/root/special/event') t(c);

更新:与过时的相同FROM OPENXML

我刚刚尝试了 FROM OPENXML 的过时方法如何处理这个问题,发现结果集中绝对没有迹象表明给定的 textCDATA节原来。 "Some value here" 的返回方式与 CDATA:

中的文本完全相同
DECLARE @doc XML = 
'<root>
  <child>Some value here </child>
  <special>
   <event><![CDATA[text->text]]></event>
   <event><![CDATA[text->text]]></event>
  </special>
</root>';

DECLARE @hnd INT;

EXEC sp_xml_preparedocument @hnd OUTPUT, @doc;  

SELECT * FROM OPENXML (@hnd, '/root',0);

EXEC sp_xml_removedocument @hnd;  

这是如何使用纯 SQL 在 XML 的子节点上包含 cdata。但;这并不理想。

SELECT 1 AS tag, 
   null AS parent, 
   '10001' AS 'Customer!1!Customer_ID!Element', 
   'AirBallon Captain' AS 'Customer!1!Title!cdata', 

   'Customer!1' = (
        SELECT 
               2 AS tag, 
               NULL AS parent, 
               'Wrapped in cdata, using explicit' AS 'Location!2!Title!cdata' 
               FOR XML EXPLICIT)

FOR XML EXPLICIT, ROOT('Customers')

包含 CDATA,但子元素使用

编码
&gt;

而不是 > 从明智的角度来看,这太奇怪了。我确定有技术解释,但它们很愚蠢,因为 FOR XML 规范没有区别。

您可以在内部子节点上包含选项 type,然后也松散 cdata.. 但是为什么哦为什么?!?!?!?!当我刚添加 cdata 时,你 (Microsoft) 会删除它吗?

<Customers>
  <Customer>
    <Customer_ID>10001</Customer_ID>
    <Title><![CDATA[AirBallon Captain]]></Title>
     &lt;Location&gt;
       &lt;Title&gt;&lt;![CDATA[wrapped in cdata, using explicit]]&gt;&lt;/Title&gt;
     &lt;/Location&gt;
 </Customer>
</Customers>