Объект XmlDocument.Ошибка загрузки, LoadXml работает:

в ответе этот вопрос, я столкнулся с ситуацией, которую я не понимаю. OP пытался загрузить 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à строка как внутренний текст узла должна быть внутри это не даст никакой ошибки в XmlDocument.Нагрузка.