Ошибка XmlDocument.Load, LoadXml работает:

Отвечая на этот вопрос, я столкнулся с ситуацией, которую я не понимаю. ОП пытался загрузить 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 ответа

Решение

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

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

Если мы хотим получить действительно технический характер, то символ, который он выбрасывает, - это "а", который равен 0xE0 в кодировке ISO-8859-1, но это недопустимый символ в UTF-8 - в частности, двоичное представление этого символа:

11100000

Если вы покопаетесь в статье в Википедии UTF-8, мы увидим, что это указывает на кодовую точку (т. Е. Символ), состоящую из 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.

Строка Umidità как внутренний текст Node должна быть внутри это не даст никакой ошибки в XmlDocument.Load.

Другие вопросы по тегам