避免在SQL XML属性中编码&符号

时间:2016-03-09 14:36:20

标签: sql sql-server xml sqlxml

图片我有一张货币表,包含例如这条记录:
- Id = 1
- 代码= EUR
- 符号=&欧元;
重要提醒:
我们数据库中的输入已经是HTML编码的属性!

现在,当我使用这个SQL语句时:

SELECT '@id'        = Currency.Id
    , '@code'       = Currency.Code
    , '@symbol'     = Currency.Symbol
FROM Currency
FOR XML PATH('currency')
    , ROOT('list')
    , TYPE
;

......遗憾的是,它导致了以下XML:

<list><currency id="1" code="EUR" symbol="&amp;euro;" /></list>

请注意,欧元符号已被重新编码,使其无效。

我该如何避免?如何获取以下XML输出:

<list><currency id="1" code="EUR" symbol="&euro;" /></list>

1 个答案:

答案 0 :(得分:2)

重新编码无效的结果完全正确 - 但不是您所期望的。你传入&euro;这是一个字符串。在XML中,它会以&amp;euro;转义,并会重新编码为&euro;

您必须停止将XML视为一种形式化的字符串。这是一个技术问题。 XML将隐式处理这个问题。

有两种方法:

  • 以字符串方式将XML转换为NVARCHAR,执行您可能需要的任何字符串操作(例如REPLACE(myXML,'&amp;euro;','&euro;')并转换回XML或

  • (我更喜欢这个!)将€作为实际符号,让XML引擎进行编码。

修改

还有一件事:SQL Server不知道&euro;实体。尝试使用&#8364;&#x20AC;

SELECT '€' AS [@EuroSign]               --works
      ,'&euro;' AS [@NamedEscapedEuro]  --will be encoded
      ,'&#8364;' AS [@EscapedEuro]      --will be encoded
FOR XML PATH('TestEuro'),ROOT('root')

SELECT --CAST('<x>'+'€'+'</x>' AS XML).value('/x[1]','nvarchar(10)') AS [@EuroSign]              --not allowed!!!
       --CAST('<x>'+'&euro;'+'</x>' AS XML).value('/x[1]','nvarchar(10)') AS [@NamedEscapedEuro] --not allowed, exists, but not known in SQL Server!
       CAST('<x>'+'&#8364;'+'</x>' AS XML).value('/x[1]','nvarchar(10)') AS [@EscapedEuro]       --works
FOR XML PATH('TestEuro'),ROOT('root')