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

KM.*_*KM. 15 t-sql sql-server sql-server-2005 for-xml-path

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

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

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
Run Code Online (Sandbox Code Playgroud)

我得到以下内容:

RowID       readable
----------- ---------------------------------------
1           a&#x20;simple&#x20;translation
2           hello&#x20;world
3           wow&#x20;you&#x20;ran&#x20;this
Run Code Online (Sandbox Code Playgroud)

但需要:

RowID       readable
----------- ---------------------------------------
1           a simple translation
2           hello world
3           wow you ran this
Run Code Online (Sandbox Code Playgroud)

除了REPLACE()让空间正确显示之外,还有什么办法吗?这也发生在我的实际代码中的换行符上.

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

Rem*_*anu 23

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

更新:

如果不清楚,您在查询中需要做的就是将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
Run Code Online (Sandbox Code Playgroud)

  • +1 - 这个答案对我有帮助.不过,我错过了`,TYPE'一段时间了. (2认同)