代码之家  ›  专栏  ›  技术社区  ›  KM.

对于XML路径(“”):转义“特殊”字符

  •  15
  • KM.  · 技术社区  · 15 年前

    这段代码基本上是根据一个字符串中的位置将字符转换为另一个字符串中相同位置的字符,并针对表中的所有行运行。

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

    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
    

    我得到以下信息:

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

    但需要:

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

    除了 REPLACE() ,是否要正确显示这些空间?在我的实际代码中,这也发生在换行符上。

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

    1 回复  |  直到 8 年前
        1
  •  23
  •   Remus Rusanu    15 年前

    您得到的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