Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 转换时转义XML特殊字符_Sql_Xml_Csv_Tsql_Sql Server 2014 - Fatal编程技术网

Sql 转换时转义XML特殊字符

Sql 转换时转义XML特殊字符,sql,xml,csv,tsql,sql-server-2014,Sql,Xml,Csv,Tsql,Sql Server 2014,我有可供我使用的csv拆分器 您只需抓取并按原样运行即可: declare @t table(data varchar(max)) insert into @t select 'a,b,c,d' insert into @t select 'e,,,h' ;with cte(xm) as ( select convert(xml,'<f><e>' + replace(data,',', '</e><e>') + '</e>&

我有可供我使用的csv拆分器

您只需抓取并按原样运行即可:

declare @t table(data varchar(max))
insert into @t select 'a,b,c,d'
insert into @t select 'e,,,h'

;with cte(xm) as 
(
    select convert(xml,'<f><e>' + replace(data,',', '</e><e>') + '</e></f>') as xm 
    from @t
)
select
    xm.value('/f[1]/e[1]','varchar(32)'),
    xm.value('/f[1]/e[2]','varchar(32)'),
    xm.value('/f[1]/e[3]','varchar(32)'),
    xm.value('/f[1]/e[4]','varchar(32)')
from cte
它失败并出现错误:字符24,非法字符

一种解决方案是动态地将&字符替换为&,如下所示:

select convert(xml,'<f><e>' + replace(replace(data,'&','&amp'),',', '</e><e>') + '</e></f>') as xm 
选择convert(xml)、+replace(replace(data)、、、、、、)+“”)作为xm
但是有几十个特殊的XML字符需要在转换时转义,我不能在其中嵌套几十个replace(replace)(replace(…)函数。这就是我所做的,而且非常混乱

如何修改上述代码以转义XML敏感字符,并产生相同的结果


谢谢!

您已经得到了Martin Smith的答案。但我认为,值得在这里为关注者提供一个答案。希望提供一些解释和进一步说明,将来可能无法访问rextester链接

如果你想一个字符串在这样的表中

DECLARE @mockup TABLE(SomeXMLstring VARCHAR(100));
INSERT INTO @mockup VALUES('This is a string with forbidden characters like "<", ">" or "&"');
--有时,人们尝试自己进行替换,并开始用相应的实体替换
和&
。但为了安全起见,这需要大量替换

--但是XML隐式地为我们做了所有这些

SELECT SomeXMLstring 
FROM @mockup
FOR XML PATH('')
--这就是结果

<SomeXMLstring>This is a string with forbidden characters like "&lt;", "&gt;" or "&amp;"</SomeXMLstring>
--结果相同,但没有标记:

This is a string with forbidden characters like "&lt;", "&gt;" or "&amp;"
--尽管这看起来像SSMS中的XML,但当用作字符串时,它将隐式地转换为
NVARCHAR(MAX)

--您可以在需要使用字符串连接构建XML的任何位置使用此函数隐式转义字符串:

SELECT CAST('<root>' + (SELECT SomeXMLstring AS [*] FOR XML PATH('')) + '</root>' AS XML)
FROM @mockup ;
选择CAST(“”+(选择SomeXMLstring作为[*]作为XML路径(“”))+“”作为XML)
来自@mockup;
最后回答你的问题 这一行必须使用以下技巧:

select convert(xml,'<f><e>' + replace((SELECT data AS [*] FOR XML PATH('')),',', '</e><e>') + '</e></f>') as xm
选择convert(xml)、+replace((选择数据作为[*]表示xml路径(“”))、、、“+”)作为xm

只需放弃该拆分器,使用不同的拆分器即可。您没有“工作csv拆分器”由于您遇到的问题。请参阅其他内容。@MartinSmith谢谢,但已经看到了该页面。它们都不好。我无法创建额外的函数,CLR也不好,我只是用递归快速地触底。您可以使用CTE轻松创建虚拟数字表,并使用基于数字表的表,而无需创建任何数据对象。@MartinSmith谢谢,但太过分了。请理解它不仅仅是关于CSV拆分,它通常是关于转换时的“转义XML字符”。可能是这样。感谢您深思熟虑的回答。Martin更快了,但更详细了,实际上在SQL中教了一两件关于XML的事情。然后我将这标记为一个答案。
<SomeXMLstring>This is a string with forbidden characters like "&lt;", "&gt;" or "&amp;"</SomeXMLstring>
SELECT SomeXMLstring AS [*]
FROM @mockup
FOR XML PATH('')
This is a string with forbidden characters like "&lt;", "&gt;" or "&amp;"
SELECT CAST('<root>' + (SELECT SomeXMLstring AS [*] FOR XML PATH('')) + '</root>' AS XML)
FROM @mockup ;
select convert(xml,'<f><e>' + replace((SELECT data AS [*] FOR XML PATH('')),',', '</e><e>') + '</e></f>') as xm