在xql server中将xml列值编码为xml

时间:2009-06-02 12:12:34

标签: sql-server xml

我有一个方法直接从数据库中获取vales,构建一个xml字符串,然后将xml写入文件。

这很好,直到我得到特殊字符,例如“'”,“<”,“&”等

有没有人知道Sql Server中允许我在选择它们时对值进行编码的东西;例如;

从myTable中选择encode(service_status)

感谢。

6 个答案:

答案 0 :(得分:5)

使用FOR XML子句。

它可以自动从多个值构建XML

WITH  q AS (
        SELECT  'Barnes & Noble' AS shop
        UNION ALL
        SELECT  'Marks & Spencer'
        )
SELECT  *
FROM    q
FOR XML AUTO, TYPE

---
<q shop="Barnes &amp; Noble" /><q shop="Marx &amp; Spencer" />

如果您只想对现有值进行编码,请使用:

SELECT  'Barnes & Noble'
FOR XML PATH('')

---
Barnes &amp; Noble

答案 1 :(得分:3)

如果你有&gt; = sql 2005,我认为将你的值填入xml元素然后将其拉回来可能是最容易的。这将授权需要编码的任何内容。

declare @x xml, @str varchar(8000), @encStr varchar(8000)
set @x = '<a/>'
set @str = '><&'

set @x.modify(
    'insert text{sql:variable("@str")}
    as first into (/a)[1]')

set @encStr = CAST(@x.query('/a/text()') as varchar(8000))
select @encStr
--returns: &gt;&lt;&amp;

答案 2 :(得分:2)

你不需要CLR也只需要在sql中执行...

create function [dbo].[fn_XMLEscape]( @s varchar(max)) returns varchar(max)
as 
begin
  declare @rs varchar(max) 
  set @rs = @s
  set @rs = replace(@rs, '&', '&amp;')
  set @rs = replace(@rs, '''', '&apos;')
  set @rs = replace(@rs, '"', '&quot;')
  set @rs = replace(@rs, '>', '&gt;')
  set @rs = replace(@rs, '<', '&lt;')
  Return( @rs)
end

答案 3 :(得分:1)

如果调用应用程序正在构建返回XML的内容,那么由调用应用程序来编码数据。如果你想从SQL Server返回XML,那么由你决定,Quassnoi的“FOR XML”答案是正确的。

答案 4 :(得分:0)

如果您使用的是SQL Server版本2005/2008,那么您很幸运,因为您可以使用CLR Functions创建自己的ENCODE函数。

A really good article can be found here

答案 5 :(得分:0)

我的变体:

CREATE FUNCTION dbo.fn_XmlEncode (@STR varchar(200))
RETURNS varchar(200)
AS
BEGIN
    IF CHARINDEX('&', @STR) > 0
    BEGIN
       DECLARE @POS1 int, @POS2 int
       SET @POS1 = CHARINDEX('&', @STR)
       WHILE @POS1 > 0 BEGIN
           IF SUBSTRING(@STR, @POS1, 5) <> '&'
              SET @STR = LEFT(@STR, @POS1 - 1) + '&' 
                  + case when @POS1 < LEN(@STR) THEN SUBSTRING(@STR, @POS1 + 1, LEN(@STR) - @POS1) ELSE '' END
           SET @POS2 = CHARINDEX('&', SUBSTRING(@STR, @POS1 + 5, LEN(@STR)))
           IF @POS2 = 0 BREAK
           SET @POS1 = @POS1 + 4 + @POS2
       END
    END
    WHILE CHARINDEX('<', @STR) > 0
       SET @STR = REPLACE(@STR, '<', '<')
    WHILE CHARINDEX('>', @STR) > 0
       SET @STR = REPLACE(@STR, '>', '>')
    RETURN @STR
END
GO
-- Tests
SELECT dbo.fn_XmlEncode('&&'), dbo.fn_XmlEncode('&<&>"&&')