Para o caminho XML ( ''): escapar caracteres “especiais”
-
20-08-2019 - |
Pergunta
Este código, basicamente, converte caracteres com base na posição em uma cadeia para o personagem na mesma posição em outra seqüência e funciona para todas as linhas na tabela.
Quando eu executar este (versão simplificada):
DECLARE @R char(40)
DECLARE @U char(40)
SET @R=' abcdefghijklmnopqrstuvwxyz!@#$%^&*()_+'+char(181)
SET @U=REVERSE(@R)
DECLARE @TestTable TABLE (RowID int identity(1,1) primary key, Unreadable varchar(500))
INSERT INTO @TestTable VALUES ('+µt$zw!*µsu+yt!+s$xy')
INSERT INTO @TestTable VALUES ('%*!!xµpxu!(')
INSERT INTO @TestTable VALUES ('pxpµnxrµu+yµs%$t')
;WITH CodeValues AS
(
SELECT
Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA
FROM Numbers
WHERE Number<=LEN(@R)
)
SELECT
t.RowID
,(SELECT
''+c.R
FROM Numbers n
INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA
WHERE n.Number<=LEN(t.Unreadable)
FOR XML PATH('')
) AS readable
FROM @TestTable t
Eu recebo a seguinte:
RowID readable
----------- ---------------------------------------
1 a simple translation
2 hello world
3 wow you ran this
Mas necessidade:
RowID readable
----------- ---------------------------------------
1 a simple translation
2 hello world
3 wow you ran this
Existe alguma maneira, diferente de REPLACE()
, para ter os espaços aparecem corretamente? Isso também acontece em quebras de linha, no meu código real.
Isso pode ser reescrito de uma maneira melhor? Eu basicamente só usou o FOR XML PATH('')
para concatenar os valores de linha individuais juntos.
Solução
O XML que você recebe é correta. É XML , e não texto, e legível como XML por um parser XML. caracteres especiais estão devidamente escapou, como deveriam ser. Seja qual for o módulo de cliente você tem que consome que XML deve analisá-lo como XML, não como texto e, em seguida, ele irá exibir corretamente.
Update:
No caso não é claro, tudo o que você precisa fazer a sua consulta é XML tratar como XML e texto como texto, não misture XML como texto, ou seja:
;WITH CodeValues AS
(
SELECT
Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA
FROM Numbers
WHERE Number<=LEN(@R)
)
, XmlValues AS (
SELECT
t.RowID
,(SELECT
''+c.R
FROM Numbers n
INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA
WHERE n.Number<=LEN(t.Unreadable)
FOR XML PATH(''), TYPE
) AS readable
FROM @TestTable t)
SELECT x.RowId,
x.readable.value('.', 'VARCHAR(8000)') as readable
FROM XmlValues AS x