9

我正在尝试将以下字符串插入到 sql xml 字段中

<?xml version="1.0" encoding="UTF-8"?>
<Response> 
    <Ip>x.x.x.x</Ip>
    <CountryCode>CA</CountryCode> 
    <CountryName>Canada</CountryName>
    <RegionCode>QC</RegionCode> 
    <RegionName>Québec</RegionName> 
    <City>Dorval</City> 
    <ZipCode>h9p1j3</ZipCode> 
    <Latitude>45.45000076293945</Latitude> 
    <Longitude>-73.75</Longitude> 
    <MetroCode></MetroCode> 
    <AreaCode></AreaCode> 
</Response>

插入代码如下所示:

INSERT 
    INTO Traffic(... , xmlGeoLocation, ...)
    VALUES (
        ...
        <!--- 
        <cfqueryparam CFSQLType="cf_sql_varchar" value="#xmlGeoLocation#">, 
        --->
        '#xmlGeoLocation#',

        ...
        )

发生了两件坏事:

  1. 魁北克变成了魁北克

  2. 我收到一条错误消息 [Macromedia][SQLServer JDBC Driver][SQLServer]XML parsing: line 8, character 16, illegal xml character

更新:

传入的测试流大多是单字节字符。

é 是一个两字节字符。特别是 C3A9

我也无法控制传入的 xml 流

4

3 回答 3

18

我要去掉标题...

我对一个有趣的小撇号有同样的问题。我认为问题在于,当字符串转换为 XML 时,它不再是 UTF-8,但 sql server 正在尝试使用标头对其进行解码。如果是 VARCHAR,则它在客户端的编码中。如果是 NVARCHAR,则为 UTF-16。以下是我测试的一些变体:

SQL (varchar, UTF-8):

SELECT CONVERT(XML,'<?xml version="1.0" encoding="UTF-8"?><t>We’re sorry</t>')

错误:

XML parsing: line 1, character 44, illegal xml character

SQL(nvarchar,UTF-8):

SELECT CONVERT(XML,N'<?xml version="1.0" encoding="UTF-8"?><t>We’re sorry</t>')

错误:XML 解析:第 1 行,字符 38,无法切换编码

SQL (varchar, UTF-16)

SELECT CONVERT(XML,'<?xml version="1.0" encoding="UTF-16"?><t>We’re sorry</t>')

错误:

XML parsing: line 1, character 39, unable to switch the encoding

SQL (nvarchar, UTF-16)

SELECT CONVERT(XML,N'<?xml version="1.0" encoding="UTF-16"?><t>We’re sorry</t>')

工作!

于 2015-02-28T19:08:53.150 回答
1

看看 w3 的这个链接,它告诉我:

在 HTML 中,有一些内置字符名称的列表,例如&eacute;for é,但 XML 没有。在 XML 中,只有五个内置字符实体:&lt;&gt;&amp;&quot;分别&apos;用于 <、>、&、" 和 '。您可以在文档类型定义中定义自己的实体,也可以使用任何 Unicode 字符(请参阅下一项)。

在 HTML 中,还有数字字符引用,例如&#38;for &。您可以引用任何 Unicode 字符,但数字是十进制的,而在 Unicode 表中,数字通常是十六进制的。XML 还允许使用十六进制引用:&#x26;例如。

这让我相信,这&#xE9;可能适用于 é 角色。

此外,来自 Microsoft 的此链接上的信息指出:

SQLXML 4.0 依赖于 SQL Server 中提供的对 DTD 的有限支持。SQL Server 允许在 xml 数据类型数据中使用内部 DTD,可用于提供默认值并用扩展内容替换实体引用。SQLXML 将 XML 数据“按原样”(包括内部 DTD)传递给服务器。您可以使用第三方工具将 DTD 转换为 XML Schema (XSD) 文档,并将带有内联 XSD 模式的数据加载到数据库中。

但是,如果您无法控制传入的 XML 流,那么所有这些都无济于事。我怀疑是否可以将 XML 文档中的 é(或任何特殊字符,除了上面提到的内置字符实体)保存到 SQL Server XML 字段中,而无需添加 DTD 或将字符替换为它的十六进制参考对应物。在这两种情况下,您都需要能够在 XML 进入数据库之前对其进行修改。

对于任何想要走“添加 DTD”路线的人来说,这只是一个简单的例子。

以下是如何将内部 DTD 添加到为 é 字符声明实体的 xml 文件中:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY eacute "&#233;">]>
<root>
  <RegionName>Qu&eacute;bec</RegionName>
</root>

如果你去这里并在页面“Ctrl+F”上搜索“eacute”,你最终会看到一个包含其他字符示例的列表,你可以将它们复制并粘贴到你自己的内部 DTD 中。

编辑

您当然可以添加上面链接中指定的所有实体:<!ENTITY eacute "&#233;"><!ENTITY .. // Next entity>,或者只是从这个文件中复制它们。我确实理解如何将内部 DTD 添加到您添加到数据库的每个 XML 文件中并不是一个好主意。我很想知道为 1 个文件添加它是否可以解决您的问题。

于 2013-04-14T04:13:02.543 回答
0

尝试改变这一点:

<RegionName>Québec</RegionName> 

至:

<RegionName><![CDATA[Québec
]]></RegionName> 
于 2013-04-14T03:40:16.347 回答