【问题标题】:SQL SERVER xml with CDATA带有 CDATA 的 SQL SERVER xml
【发布时间】:2016-11-24 20:19:44
【问题描述】:

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

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

我还没有创建数据库,我无法更改信息在其中的存储方式,但我可以通过选择检索它。对于我使用的提取 选择演员(替换(xml,'utf-8','utf-16')作为xml) 从表

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

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

【问题讨论】:

  • 嗨,我没有时间测试给定的解决方案,我会尽快更新问题。如果您有其他解决方案,我很乐意对其进行测试

标签: sql sql-server xml cdata


【解决方案1】:

嗯,这是 - 据我所知 - 在正常方式下是不可能的......

CDATA 部分只有一个原因:在为懒惰的人包含无效字符...

CDATA 根本不需要,因此通常的 XML 方法并不真正支持。或者换句话说:内容被正确转义的方式支持。实际上,CDATA 中正确转义的内容和未转义的内容之间没有区别! (好吧,有一些细微的区别,比如包括]]&gt; 一个CDATA-section 和一些更小的专业......)

最大的问题是:为什么?

之后你想做什么?

试试这个。包含的文本原样

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 的过时方法如何处理这个问题,发现结果集中绝对没有迹象表明给定的 text 最初位于 CDATA 部分中。 “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;  

【讨论】:

    【解决方案2】:

    这是使用纯 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>
    

    【讨论】:

      猜你喜欢
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      相关资源
      最近更新 更多