まず、クイズを出しましょう。
.NET Framework 1.1上で動作するC#のサンプルソースです。
これを実行した場合、どのような結果になるか、当ててみてください。
C#と.NET Framework 1.1上のXML DOMの知識がある人が対象です。
using System;
using System.Xml;
class DomLoadSave
{
[STAThread]
static void Main(string[] args)
{
const string filename = @"c:\%AB.xml";
const string src = "<a/>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(src);
doc.Save(filename);
XmlDocument doc2 = new XmlDocument();
doc2.Load(filename);
Console.WriteLine(doc2.OuterXml);
}
}
分かりましたか?
結果は、以下のような例外です。
'System.IO.FileNotFoundException' のハンドルされていない例外が system.xml.dll で発生しました。
追加情報 : ファイル "c:\«.xml" が見つかりませんでした。
なぜ、このような結果になるのか、理由が分かりますか?
これはバグではありません。
stringを引数に取るLoadメソッドとSaveメソッドは、引数の扱いが異なるというのが、理由です。よく説明を読むと、LoadメソッドはURLだと書いてありますが、Saveメソッドはそう書いてありません。つまり、Loadメソッドは引数をURLとして解釈する際に、ファイルとしてのアクセスも許しているだけの話であって、Windowsのファイル名記述のルールに厳密に合致しているわけではないのです。実際、%記号があると、それはURLエンコードと見なされて解釈されます。これにより、%記号を含む文字列をファイル名として与えると、LoadメソッドとSaveメソッドは異なる対象にアクセスしに行きます。
これを回避するには、Loadメソッドにファイル名を文字列として渡すのではなく、ファイルをストリームとして開いてからそれを渡すようにすると良いでしょう。
というバグ取りを現在作業中であったりします…… (涙) うっかり間違えやすいのよね、これ。
追記: DOMだけでなく、XmlReader/Writer系のクラスにも同じ罠があるらしい……。