5

如果我做

Declare @t table(Email xml)
Declare @email varchar(100) = 'xxx&xx@monop.com'
Insert into @t  
select '<Emails> <Email>' + @email +'</Email></Emails>'
select * From @t

我会收到预期的错误

消息 9411,级别 16,状态 1,第 8 行 XML 解析:第 1 行,字符 27,需要分号

我几乎在任何地方(包括 SO)都找到了一种解决方案,replace '&' with '&amp;它可以工作

Insert into @t  
select CAST('<Emails><Email>' + REPLACE(@email, '&', '&amp;') + '</Email></Emails>' AS XML)

输出

<Emails><Email>xxx&amp;xx@monop.com</Email></Emails>

但是,我正在尝试使用 CData 方法(只是解决问题的另一种方法)

Declare @t table(Email xml)
Declare @email varchar(100) = 'xxx&xx@monop.com'
Insert into @t  
Select CAST('<![CDATA[Emails> <Email>' + @email + '</Email> </Emails]]>' AS XML)
select * From @t

当我得到以下输出时

Emails&gt; &lt;Email&gt;xxx&amp;xx@monop.com&lt;/Email&gt; &lt;/Emails

我想要实现的是按原样存储数据,即所需的输出应该是

<Emails><Email>xxx&xx@monop.com</Email></Emails>

有可能吗?

我知道如果 xml 无法理解的任何其他特殊字符将作为输入传递给它,则替换函数将失败,例如 '<' i 在这种情况下,我们需要再次替换它......

谢谢

4

2 回答 2

3

标签是 PCDATA,而不是 CDATA,所以不要将它们放在 CDATA 部分。

于 2012-06-10T06:52:36.937 回答
2

当您使用 XML 时,您应该使用 SQL Server 的与 XML 相关的功能。

例如:

/* Create xml and add a variable to it */
DECLARE 
    @xml xml = '<Emails />',
    @email varchar(100) = 'xxx&xx@monop.com';

SET @xml.modify ('insert (
    element Email {sql:variable("@email")}
) into (/Emails)[1]');

SELECT @xml;

/* Output:
<Emails>
  <Email>xxx&amp;xx@monop.com</Email>
</Emails>
*/

/* Extract value from xml */

DECLARE @email_out varchar(200);

SET @email_out = @xml.value ('(/Emails/Email)[1]', 'varchar (200)');

SELECT @email_out; /* Returns xxx&xx@monop.com */

祝你好运

罗马

于 2012-06-10T08:27:15.717 回答