2011-09-21 13 views
8

this questionと答えると、私は理解できない状況に遭遇しました。 OPは次の場所からXMLをロードしようとしていた。http://www.google.com/ig/api?weather=12414&hl=itXmlDocument.Loadが失敗し、LoadXmlが機能します。

明白な解決策は以下のとおりです。

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宣言はエンコードを省略しています。

+0

WebClient htmlencodesは可能でしょうか? – Nicolai

答えて

12

WebClientは(ASCIIベースであり、この場合ISO-8859-1に、文字当たりすなわち8ビット)正しい符号を決定するために、HTTPレスポンスのヘッダに符号化情報を使用し

XmlDocument.Loadが使用していないように見えこの情報と、エンコーディングがxml宣言にもないので、エンコーディングを推測して間違ってしまいます。 UTF-8を選ぶと信じるために、周りを掘ることが私を導く。

私たちが本当にテクニカルになるためには、ISO-8859-1エンコーディングの0xE0である "à"ですが、これはUTF-8の有効な文字ではありません。この文字は次のとおりです。

11100000 

あなたはUTF-8 Wikipedia articleの周りを掘るを持っている場合、我々は、これは次の形式を取る3バイトの合計からなるコード・ポイント(すなわち文字)を示していることがわかります。

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

ただし、 ISO-8859-1の0x3Aと0x20である ":"が次の2文字になります。これは、私たちが実際に終わる何を意味している:シーケンスの第二または第三バイトはいずれも、(継続を示すことになる)2つの最上位ビットとして10を持っているので、この文字がで意味をなさない

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

UTF-8。

+0

Reflectorを開く... – spender

+0

コードを見ると、Loadは 'XmlTextReader'をインスタンス化しますが、エンコーディングを設定しようとはしません。 – spender

+0

@spenderええ、私はILSpyの周りを見ていましたが、何が起こっていたのかを見てみるのは難解でした。面白い質問ですが、これに感謝しました。:-) – Justin

2

ノードinnertextとしてのUmidità文字列は、<である必要があります。 [CDATA [Umidità]]>これはXmlDocument.Loadにエラーを表示しません。

+0

この質問はXMLを修正する方法ではなく、上記の質問に記載されている2つの方法の間で動作が異なる理由は何ですか。 – spender

+1

実際には、CDATAタグは文字データをパーサーに示すので、XML構造( "<"など)はエスケープする必要はありませんが、この場合はCDATAタグを使用してエンコードの問題は発生しません。 – Justin

関連する問題