FOR XML PATH(''):转义“特殊”字符

时间:2022-12-16 00:24:11

This code basically translates characters based on position in one string to the character at the same position in another string and it runs for all rows in the table.

此代码基本上将基于一个字符串中的位置的字符转换为另一个字符串中相同位置的字符,并且它针对表中的所有行运行。

When I run this (simplified version):

当我运行此(简化版)时:

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

I get the following:

我得到以下内容:

RowID       readable
----------- ---------------------------------------
1           a&#x20;simple&#x20;translation
2           hello&#x20;world
3           wow&#x20;you&#x20;ran&#x20;this

But need:

但需要:

RowID       readable
----------- ---------------------------------------
1           a simple translation
2           hello world
3           wow you ran this

Is there any way, other than REPLACE(), to have the spaces show up properly? This also happens on line breaks, in my actual code.

有什么方法,除了REPLACE(),让空格正确显示?在我的实际代码中,这也发生在换行符上。

Can this be rewritten in a better way? I basically just used the FOR XML PATH('') to concatenate the individual row values together.

这可以用更好的方式重写吗?我基本上只使用FOR XML PATH('')将各个行值连接在一起。

1 个解决方案

#1


22  

The XML you get is correct. It is XML, not text, and readable as XML by an XML parser. Special characters are properly escaped, as they should be. Whatever client module you have that consumes that XML should parse it as XML, not as text, and then it will display properly.

你得到的XML是正确的。它是XML,而不是文本,XML解析器可以读取XML。特殊字符应该正确转义。无论您使用哪种客户端模块,XML都应该将其解析为XML,而不是文本,然后它将正确显示。

Update:

更新:

In case is not clear, all you need to do in your query is to treat XML as XML and text as text, not mix XML as text, ie:

如果不清楚,您在查询中需要做的就是将XML视为XML,将文本视为文本,而不是将XML作为文本混合,即:

;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

#1


22  

The XML you get is correct. It is XML, not text, and readable as XML by an XML parser. Special characters are properly escaped, as they should be. Whatever client module you have that consumes that XML should parse it as XML, not as text, and then it will display properly.

你得到的XML是正确的。它是XML,而不是文本,XML解析器可以读取XML。特殊字符应该正确转义。无论您使用哪种客户端模块,XML都应该将其解析为XML,而不是文本,然后它将正确显示。

Update:

更新:

In case is not clear, all you need to do in your query is to treat XML as XML and text as text, not mix XML as text, ie:

如果不清楚,您在查询中需要做的就是将XML视为XML,将文本视为文本,而不是将XML作为文本混合,即:

;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