недопустимый символ xml на SQL Insert
Я пытаюсь вставить следующую строку в поле 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#',
...
)
случаются две плохие вещи:
Квебек превращается в Québec
Я получаю сообщение об ошибке говорящее
[Macromedia][SQLServer JDBC Driver][SQLServer]XML parsing: line 8, character 16, illegal xml character
обновление:
входящий тестовый поток состоит в основном из однобайтовых символов.
é-двухбайтовый символ. Особенно C3A9
также у меня нет контроля над входящим потоком xml
3 ответов
Я собираюсь снять заголовок...
у меня такая же проблема с забавным маленьким Апострофом. Я думаю, проблема в том, что к тому времени, когда строка преобразуется в 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>')
работала!
попробуйте изменить это:
<RegionName>Québec</RegionName>
в:
<RegionName><![CDATA[Québec
]]></RegionName>
посмотри ссылке из w3 он говорит мне, что:
в HTML есть список некоторых встроенных имен символов, таких как
é
для é, но XML не имеет этого. В XML существует только пять встроенных символьных сущностей:<
,>
,&
,"
и'
Для , &, " и ' соответственно. Можно определить собственные сущности в определении типа документа или использовать любой символ Юникода (см. Следующий элемент).в HTML, есть также числовые ссылки на символы, такие как
&
для &. Вы можете ссылаться на любой символ Юникода, но число десятичное, тогда как в таблицах Юникода число обычно шестнадцатеричное. XML также позволяет шестнадцатеричные ссылки:&
например.
это заставляет меня поверить, что,é
может работать для символа é.
также информация на этом ссылке из Штатов Microsoft что:
SQLXML 4.0 полагается на ограниченную поддержку DTDs, предоставляемую в SQL Server. SQL Server допускает наличие внутреннего DTD в xml-данных типа данных, которые могут использоваться для предоставления значений по умолчанию и замены ссылок на сущности их расширенным содержимым. SQLXML передает XML-данные "как есть" (включая внутренний DTD) на сервер. Вы можете конвертировать DTDs в документы XML-схемы (XSD) с помощью сторонних инструментов и загружать данные с помощью встроенных схем XSD в база данных.
но все это не поможет вам, если у вас нет контроля над входящим потоком XML. Я сомневаюсь, что можно сохранить é (или любой специальный символ, за исключением встроенных символьных сущностей, упомянутых выше) внутри XML-документа в XML-поле SQL Server, не добавляя DTD или не заменяя символ его шестнадцатеричным ссылочным аналогом. В обоих случаях вам нужно будет иметь возможность изменить XML, прежде чем он пойдет в базу данных.
просто быстрый пример для тех, кто хочет спуститься по маршруту "добавление DTD".
вот как добавить внутренний DTD в xml-файл, который объявляет сущность для символа é:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY eacute "é">]>
<root>
<RegionName>Québec</RegionName>
</root>
если вы идете здесь и поиск на странице "Ctrl+F" для "eacute", вы попадаете в список с примерами для других символов, которые вы можете просто скопировать и вставить в свой собственный внутренний шаблон DTD.
редактировать
вы можете, конечно, добавить все объекты, как они указаны в ссылке выше: <!ENTITY eacute "é"><!ENTITY .. // Next entity>
, или просто скопируйте их все из этого . Я понимаю, как добавление внутреннего DTD в каждый XML-файл, который вы добавляете в базу данных, не такая хорошая идея. Мне было бы интересно узнать, исправляет ли добавление его для файла 1 вашу проблему.