8

我有这个疑问,

DECLARE @Result XML;
SELECT @Result = (  SELECT  PD.* 
                FROM    [ProductDetailedDescriptions] PD
                        LEFT JOIN [Products] P ON (PD.ProductID= P.ID)
                WHERE   PD.ProductID = 23
                        AND P.RetailerID = 1
                        AND PD.LanguageID = 1
                ORDER BY [ORDER]
                FOR XML AUTO, ELEMENTS, ROOT('root')
            )

这抛出XML parsing: line 1, character 2038, illegal xml character. 当我只选择时,

SELECT  PD.* 
FROM    [ProductDetailedDescriptions] PD
        LEFT JOIN [Products] P ON (PD.ProductID= P.ID)
WHERE   PD.ProductID = 23
        AND P.RetailerID = 1
        AND PD.LanguageID = 1
ORDER BY [ORDER]
FOR XML AUTO, ELEMENTS, ROOT('root')

它显示以下xml,

<root>
   ..............................................
   ..............................................
  <PD>
    <ID>4187</ID>
    <ProductID>23</ProductID>
    <Header>aa</Header>
    <Description>with &#x3;other</Description>
    <Order>7</Order>
    <LanguageID>1</LanguageID>
  </PD>

注意#x3。在我的应用程序中,它只是一个空间。它是 SQL Server 的错误吗?

4

1 回答 1

11

&#x03;是 XML 中的无效字符。

来自可扩展标记语言 (XML) 1.0(第五版)

字符 ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

您的有效查询可以简化为:

select cast(0x3 as char(1)) col
for xml raw

上述查询的输出是一个表,其中一行一列的数据类型为nvarchar(max)

分配给 XML 变量时会出现错误。

declare @XML xml = 
(
  select cast(0x3 as char(1)) col
  for xml raw
)

消息 9420,级别 16,状态 1,第 1 行 XML 解析:第 1 行,字符 16,非法 xml 字符

或者,当您指定type指令时,该列将是一个 XML 列,您会得到一个更详细的错误。

select cast(0x3 as char(1)) col
for xml raw, type

消息 6841,级别 16,状态 1,第 1 行 FOR XML 无法序列化节点“col”的数据,因为它包含 XML 中不允许的字符 (0x0003)。要使用 FOR XML 检索此数据,请将其转换为二进制、varbinary 或图像数据类型并使用 BINARY BASE64 指令。

在生成 XML 之前,您必须删除非法字符。

declare @XML xml =
replace((
       select cast(0x3 as char(1)) col
       for xml raw
       ), '&#x03;', '')
于 2013-08-05T10:03:09.750 回答