我的数据库中有一个表,其中包含一个包含xml的列。列类型为nvarchar(max)。 xml以这种方式形成
{{1}}
我没有创建数据库,我无法更改信息存储在其中的方式,但我可以使用select检索它。对于我使用的提取 select cast(replace(xml,'utf-8','utf-16')为xml) 从表
除cdata外,它的效果很好,其查询输出中的内容为:text - >文本
有没有办法检索CDATA标签?
答案 0 :(得分:2)
嗯,据我所知,这是正常情况下不可能的......
CDATA
部分有一个唯一原因:在 XML中为懒人包含无效字符 ...
CDATA
,因此普通的XML方法并不支持它。或者换句话说:内容被正确转义得到支持。实际上CDATA
内的正确转义内容与未转义内容之间没有区别! (好的,有一些细微差别,比如在 a ]]>
- 部分中加入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
处理过时的方法,并发现结果集中绝对没有迹象表明给定的文本在CDATA
范围内最初的部分。这里的“某些值”与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;
答案 1 :(得分:0)
这是使用纯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,但使用
对Child元素进行编码>
代替> 从明智的角度来看,这太奇怪了。我敢肯定有技术上的解释,但是它们很愚蠢,因为 FOR XML 规范没有区别。
您可以在内部子节点上包含选项type
,然后也松开cdata。
但是为什么?为什么?!?!?!?!我刚添加cdata时,您会删除吗?
<Customers>
<Customer>
<Customer_ID>10001</Customer_ID>
<Title><![CDATA[AirBallon Captain]]></Title>
<Location>
<Title><![CDATA[wrapped in cdata, using explicit]]></Title>
</Location>
</Customer>
</Customers>