Проблема парсинга XML в немецкой культуре - ASP.NET - PullRequest
1 голос
/ 02 апреля 2011

Платформа кодирования : ASP.NET WebForms 4.0 с C #

Справочная информация : я читаю некоторые значения из XML, и все работает в моей локали (en-US). XML выглядит так

<?xml version="1.0" encoding="utf-32" ?>
<settings>
  <UserRegistration>AutoAuthorize</UserRegistration>
  <OpenIDProfile>PromptUser</OpenIDProfile>
  <EnableSpamProtection>Yes</EnableSpamProtection>
  <MaxAllowedOpenID>2</MaxAllowedOpenID>
  <WebsiteURL>http://localhost:70707/blah/</WebsiteURL>
  <FacebookOAuthURL>https://graph.facebook.com/oauth/authorize?</FacebookOAuthURL>
  <FacebookAccessTokenURL>https://graph.facebook.com/oauth/access_token?</FacebookAccessTokenURL>
  <FacebookRedirectPage>ausgefüllt.aspx</FacebookRedirectPage>
  <FacebookAppID>192328104139846</FacebookAppID>
  <FacebookAppKey>29daeb58d8ae84cc22181f4073e4ed9d</FacebookAppKey>
  <FacebookAppSecret>b94e9ddd20efc47b3227e7333925fdd8</FacebookAppSecret>
  <FacebookScope>email</FacebookScope>
  <EmailSettingsDisplayName>admin</EmailSettingsDisplayName>
  <EmailSettingsEmail>blah@blah.com</EmailSettingsEmail>
  <EmailSettingsPassword>192185135098207157230060249027191124199097098215</EmailSettingsPassword>
</settings>

Задача

Я завернул все это своему клиенту для тестирования. Среда тестирования

Сервер: Windows Server 2008 R2, 64-разрядная
Язык: немецкий (de-DE)

И теперь, когда я пытаюсь прочитать XML, Элма выдает две ошибки. Первая ошибка

System.Xml.XmlException: '?', шестнадцатеричное значение 0xA000D, является неправильный символ. Линия 1, позиция 40. at System.Xml.XmlTextReaderImpl.Throw (String res, String [] args) в System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace () в System.Xml.XmlTextReaderImpl.ParseDocumentContent () в System.Xml.Linq.XDocument.Load (XmlReader читатель, параметры LoadOptions) в System.Xml.Linq.XDocument.Load (String URI, параметры LoadOptions) в Administrator_SiteSettings.SaveSettingsButton_Click (Объект отправитель, EventArgs e) в C: \ Полотна \ ThirdPartyLogins \ Administrator \ SiteSettings.aspx.cs: строка 48

Я передаю эти значения узла XML в словарь, и эта ошибка сопровождается ошибкой ключа не найден для словаря.
Является ли кодирование виновником?
Что может быть не так в моем коде?
<Ч /> Обновление : Просто прочитайте UTF-8, UTF-16 и UTF-32 . Поможет ли переход на utf-8? <Ч /> Update2 : две вещи, которые могли бы прояснить проблему больше.

1) При изменении кодировки на utf-16 появилась новая ошибка

в utf-16 его System.Xml.XmlException: '.', шестнадцатеричное значение 0x00, является неправильный символ. Линия 1, позиция 39.

2) Вставленный ранее XML не был завершен. У него было еще несколько узлов с некоторым URL в качестве данных узла. Это будет проблемой? Также обновили XML.

<Ч />

1 Ответ

5 голосов
/ 02 апреля 2011

Краткий ответ: Да, кодировка является виновником; правильная кодировка - utf-16.

Длинный ответ: подсказка лежит в тексте исключения, где написано «шестнадцатеричное значение 0xA000D» и «строка 1, позиция 40».

Когда XmlReader читает ваш файл, он сначала читает декларацию XML (все между <?xml и ?>), чтобы определить, какую кодировку использовать для остальной части файла. В этом случае в декларации говорится UTF-32. Поэтому сразу после прочтения символа > в конце объявления он переключается на использование кодировки UTF-32. Как объясняется в вашей статье, UTF-32 использует 4 байта для представления каждого символа, поэтому XmlReader считывает следующие 4 байта из файла и пытается интерпретировать их как символ. (Это соответствует вашему сообщению об ошибке, поскольку позиция 1 в строке 40 находится сразу после символа >.)

Если бы файл действительно был UTF-32, какими были бы следующие 4 байта? Ну, следующая вещь в файле после символа > - это новая строка, состоящая из двух символов, возврата каретки и перевода строки (в Unicode, 0D и 0A соответственно). Таким образом, мы ожидаем, что следующие 4 байта будут 0D 00 00 00, а следующие 4 байта будут 0A 00 00 00 (помните, что Windows * little-endian ).

Но, как говорится в сообщении об ошибке, фактическим считыванием «символа» было A000D, что означает, что следующие 4 байта были 0D 00 0A 00 (опять же, помните little-endian). Это довольно близко, но очевидно, что для каждого символа вместо 4 используются только 2 байта. Ну, у нас есть название для этого, не так ли? Это называется UTF-16!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...