Сбой XmlDocument.Load, LoadXml работает: - PullRequest
8 голосов
/ 21 сентября 2011

Отвечая на этот вопрос , я столкнулся с ситуацией, которую я не понимаю. ОП пытался загрузить XML из следующего местоположения: http://www.google.com/ig/api?weather=12414&hl=it

Очевидное решение:

string m_strFilePath = "http://www.google.com/ig/api?weather=12414&hl=it";
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(m_strFilePath); //Load NOT LoadXml

Однако это не так с

XmlException: недопустимый символ в заданной кодировке. Строка 1, позиция 499.

Кажется, он задыхается от à из Umidità.

OTOH, отлично работает следующее:

var m_strFilePath = "http://www.google.com/ig/api?weather=12414&hl=it";
string xmlStr;
using(var wc = new WebClient())
{
    xmlStr = wc.DownloadString(m_strFilePath);
}
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlStr);

Я озадачен этим. Кто-нибудь может объяснить, почему первый отказывает, а второй работает нормально?

Примечательно, что в декларации xml документа отсутствует кодировка.

Ответы [ 2 ]

12 голосов
/ 21 сентября 2011

WebClient использует информацию кодирования в заголовках ответа HTTP для определения правильной кодировки (в данном случае ISO-8859-1 , которая основана на ASCII, то есть 8 бит на символ)

Похоже, XmlDocument.Load не использует эту информацию, и поскольку кодировка также отсутствует в объявлении xml, она должна угадать кодировку и ошибиться. Некоторое копание заставляет меня поверить, что он выбирает UTF-8.

Если мы хотим получить действительно техническую информацию, символ, который он выдает, это «à», что равно 0xE0 в кодировке ISO-8859-1, но это не допустимый символ в UTF-8 - в частности, двоичное представление этого персонажа:

11100000

Если вы покопались в статье UTF-8 Wikipedia , мы увидим, что это указывает на кодовую точку (т. Е. Символ), состоящую из 3 байтов, которые принимают следующий формат:

Byte 1      Byte 2      Byte 3
----------- ----------- -----------
1110xxxx    10xxxxxx    10xxxxxx

Но если мы оглянемся на документ, следующие два символа - это «:», что соответствует 0x3A и 0x20 в ISO-8859-1. Это означает, что мы на самом деле получаем:

Byte 1      Byte 2      Byte 3
----------- ----------- -----------
11100000    00111010    00100000

Ни 2-й, ни 3-й байты последовательности не имеют 10 в качестве двух старших значащих битов (что указывает на продолжение), и поэтому этот символ не имеет смысла в UTF-8.

2 голосов
/ 21 сентября 2011

Строка Umidità как внутренний текст узла должна быть внутри <![CDATA [Umidità]]> это не приведет к ошибке в XmlDocument.Load.

...