给出: xml字符串包含如下子字符串:
N'<node action="i" s=""petya""></node>'
如果字符串包含双“”,我该怎么做:
例如,结果:
N'<node action="u" s="petya"></node>'
答案 0 :(得分:2)
用您的列名替换@String:
DECLARE @string NVARCHAR(100)=N'<node action="i" s=""petya""></node>'
SELECT CASE WHEN @string LIKE '%""%' THEN
REPLACE(SUBSTRING(@STRING,1,CHARINDEX('action="',@string,1)-1)+'action="u"'
+SUBSTRING(@STRING,CHARINDEX('action="',@string,1)+10,LEN(@STRING)),'""','"')
ELSE @STRING END
答案 1 :(得分:2)
晚期答案-只是提出一种替代方法(已经+1 Luv)
示例
Declare @S nvarchar(max) = N'<node action="i" s=""petya""></node>'
Select @S = replace(@S,sFrom,sTo)
From ( values ( 'action="i"','action="u"')
,( 'action="a"','action="u"')
,( 'action="d"','action="u"') -- Assuming a limited number of actions
,( '=""','="') -- Leading ""
,( '"">','">') -- Trailing ""
,( '"" ','" ') -- Trailing ""
) A(sFrom,sTo)
Select @S
返回
<node action="u" s="petya"></node>
编辑-用于多个/条件节点
Declare @S nvarchar(max) = N'<node action="i" n="0" s=""petya""></node> <node action="i" n="2" s="vasya"></node>'
;with cte as (
Select A.RetSeq
,A.RetVal
,NewVal = case when patindex('%""[a-z,0-1]%""%',A.RetVal)=0
then A.RetVal
else replace(stuff(A.RetVal,B.RetPos,len(B.RetVal),'u'),'""','"')
end
From [dbo].[tvf-Str-Extract](@S,'<','>') A
Outer Apply [dbo].[tvf-Str-Extract](A.RetVal,'action="','" ') B
)
Select @S = Stuff((Select '<' +NewVal+'>' From cte Order By RetSeq For XML Path(''),TYPE).value('(./text())[1]','varchar(max)'),1,0,'')
Select convert(xml,@S)
返回有效的XML
<node action="u" n="0" s="petya" />
<node action="i" n="2" s="vasya" />
表值函数
厌倦了提取字符串(左,右,charindex,patindex等),我修改了一个parse / split函数以接受两个非相似的定界符。
CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1)
From (
Select *,RetVal = Substring(@String, N, L)
From cte4
) A
Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters
Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/