Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как заменить символы в строке?  [new]
256k
Member

Откуда: с.Торчилово, Псковская обл.
Сообщений: 437
Дано: хмл строка, в которой может встречаться такая подстрока:

N'<node action="i" s=""petya""></node>'

чего хотелось бы в идеальном случае:
если s содержит строку с двойными кавычками(что уже ошибка), тогда
заменить на одинарныею и, если такое есть то сделать в этом же тэге action="u", не важно, что там было до того.

Пример результата:
N'<node action="u" s="petya"></node>'


Как такое сделать?
21 сен 18, 13:12    [21681914]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
прочитать в хелпе про ф-цию replace()
21 сен 18, 14:08    [21681984]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
court
Member

Откуда:
Сообщений: 1956
declare @s varchar(max) = N'<node action="i" s=""petya""></node><node action="i" s="vasya"></node>'
set @s = replace(@s,'=""','="&quot;')
set @s = replace(@s,'""','&quot;"')
declare @xml xml = cast(@s as xml)

;with cte as (
	select 
		[action]=t.c.value('@action', 'varchar(20)')
		,s		=t.c.value('@s', 'varchar(100)')
	from @xml.nodes('node') as t(c)
)
select 
	 case when s like '"%"' then 'u' else [action] end			as '@action'
	 ,case when s like '"%"' then substring(s, 2, len(s)-2) else s end	as '@s'
from cte
for xml path('node')
21 сен 18, 14:29    [21682031]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
court
declare @s varchar(max) = N'<node action="i" s=""petya""></node><node action="i" s="vasya"></node>'
set @s = replace(@s,'=""','="&quot;')
set @s = replace(@s,'""','&quot;"')


изящно, просто, со вкусом. браво!
21 сен 18, 14:34    [21682038]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
256k
Member

Откуда: с.Торчилово, Псковская обл.
Сообщений: 437
Maxx
прочитать в хелпе про ф-цию replace()


даладно, одной функцией не отделаться
21 сен 18, 15:12    [21682102]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
256k
Member

Откуда: с.Торчилово, Псковская обл.
Сообщений: 437
court
declare @s varchar(max) = N'<node action="i" s=""petya""></node><node action="i" s="vasya"></node>'
set @s = replace(@s,'=""','="&quot;')
set @s = replace(@s,'""','&quot;"')
declare @xml xml = cast(@s as xml)

;with cte as (
	select 
		[action]=t.c.value('@action', 'varchar(20)')
		,s		=t.c.value('@s', 'varchar(100)')
	from @xml.nodes('node') as t(c)
)
select 
	 case when s like '"%"' then 'u' else [action] end			as '@action'
	 ,case when s like '"%"' then substring(s, 2, len(s)-2) else s end	as '@s'
from cte
for xml path('node')



Красиво, но вот в таком случае, когда есть другие теги - они теряются
declare @s varchar(max) = N'<node action="i" mumu="1" s=""petya""></node><node action="i" mumu="2" s="vasya"></node><node action="x" mumu="3" s="kolya"></node>'
set @s = replace(@s,'=""','="&quot;')
set @s = replace(@s,'""','&quot;"')
declare @xml xml = cast(@s as xml)

;with cte as (
	select 
		[action]=t.c.value('@action', 'varchar(20)')
		,s		=t.c.value('@s', 'varchar(100)')
	from @xml.nodes('node') as t(c)
)
select 
	 case when s like '"%"' then 'u' else [action] end			as '@action'
	 ,case when s like '"%"' then substring(s, 2, len(s)-2) else s end	as '@s'
from cte
for xml path('node')
21 сен 18, 15:15    [21682106]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
court
Member

Откуда:
Сообщений: 1956
256k
но вот в таком случае, когда есть другие теги - они теряются
дык, добавить эти "другие теги" в формирование нового xml-я (в cte и в запрос for xml) и всё

или их много/заранее не известные атрибуты ?
Если второе, то можно через XQuery поменять только нужные атрибуты, а всё остальное останеться как было. Типа этого что-то:
declare @s varchar(max) = N'<node action="i" mumu="1" s=""petya""></node><node action="i" mumu="2" s="vasya"></node><node action="x" mumu="3" s=""kolya""></node>'
set @s = replace(@s,'=""','="&quot;')
set @s = replace(@s,'""','&quot;"')

declare @xml xml = cast(@s as xml)

select @xml

while @xml.query('data(/node[contains(@s,"""")]/@action)').value('text()[1]', 'varchar(100)') is not null
begin
	set @xml.modify('  
	  replace value of (/node[contains(@s,"""")]/@action)[1]  
	  with     "u"  
	');
	set @xml.modify('  
	  replace value of (/node[contains(@s,"""")]/@s)[1]  
	  with     substring((/node[contains(@s,"""")]/@s)[1], 2, string-length((/node[contains(@s,"""")]/@s)[1]) - 2)  
	');
end

select @xml
21 сен 18, 16:22    [21682185]     Ответить | Цитировать Сообщить модератору
 Re: Как заменить символы в строке?  [new]
invm
Member

Откуда: Москва
Сообщений: 9116
256k,

Как-то так:
declare @s varchar(max) = N'<node mumu = "0"/><node action="i" mumu="1" s=""petya""></node><node action="i" mumu="2" s="vasya"></node><node action="x" mumu="3" s="kolya"></node>';

with cte as
(
select
 c.f,
 d.n.value('local-name(.)', 'varchar(100)') as attr_name,
 d.n.value('.', 'varchar(100)') as attr_value,
 dense_rank() over (order by b.n) as r
from
 (
  select
   cast(string_agg(s + case rn % 2 when 0 then '"&quot;' when 1 then '&quot;"' end, '') within group (order by rn) as xml)
  from
   (select value, row_number() over (order by (select 1)) - 1 from string_split(replace(@s, '""', char(1)), char(1))) t(s, rn)
 ) a(x) cross apply
 a.x.nodes('node') b(n) cross apply
 (select charindex('"', b.n.value('@s', 'varchar(100)'))) c(f) cross apply
 b.n.nodes('@*') d(n)
)
select
 cast(string_agg(s, '') within group (order by r) as xml)
from
 (
  select
   r,
   '<node> ' + string_agg(attr_name + ' = "' +
     case
      when attr_name = 'action' and f > 0 then 'u'
      when attr_name = 's' and f > 0 then replace(attr_value, '"', '')
      else attr_value
     end +
   '"', ' ') + '</node>'
  from
   cte
  group by
   r
 ) t(r, s);
21 сен 18, 18:38    [21682293]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить