.NET でオブジェクトを XML にシリアライズする方法

これは超有名。Web で調べるとすぐに出てくる。.NET でデータをいじる分散アプリを作る人であれば結構知っている。
なお、この方法ではクラスの public フィールド、または public プロパティしかシリアライズできないので注意。
private なフィールドを含めて内部データをそのままとっておける SoapFormatter や BinaryFormatter というのもあるが、SoapFormatter はジェネリックスや Hashtable のようなデータがある場合は使えず、BinaryFormatter はよくわからないバイナリデータがべろべろーと出てきて、他のアプリケーションで読めない。

public static byte[] ObjectToXml(object o, Type t)
{
	MemoryStream ms = new MemoryStream();
	XmlSerializer x = new XmlSerializer(t);
	x.Serialize(ms, o);
	return ms.ToArray();
}

.NET でクラスの型情報を XML スキーマ (.xsd) として出力する方法

これは実はあまり有名ではない。SDK に付いてくる XSD.exe を使えば、.NET のアセンブリ (DLL など) とその中にあるクラス名を指定して、そのクラスの型情報を .xsd に出力できるのだが、XSD.exe がやっていることをプログラムの中で同じように自動的にやりたい場合 (しかも、ファイルに出力するのではなく、MemoryStream などを経由して byte[] で取得したい場合) などの方法は、Web で調べてもあまり出てこない。


そこで XSD.exe の動作を解析したところ、どうやら、以下のようにやればうまくいくということがわかった。

// 型から XML スキーマを生成  汚いコードやな
public static byte[] GetXmlSchemaFromType(Type type)
{
	XmlSchemas sms = new XmlSchemas();
	XmlSchemaExporter ex = new XmlSchemaExporter(sms);
	XmlReflectionImporter im = new XmlReflectionImporter();
	XmlTypeMapping map = im.ImportTypeMapping(type);
	ex.ExportTypeMapping(map);
	sms.Compile(null, false);

	MemoryStream ms = new MemoryStream();
	StreamWriter sw = new StreamWriter(ms);
	foreach (System.Xml.Schema.XmlSchema sm in sms)
	{
		sm.Write(sw);
	}
	sw.Close();

	byte[] data = ms.ToArray();
	return data;
}


上記の XmlSchemaExporter とかいうクラスは、リファレンスを見ると、内部的に使っているものなので直接呼び出すなというようなことが書いてあるので、将来仕様が変わるかも知れないので注意。
それでもやっていることは XSD.exe の処理内容と同一なので、たぶん大丈夫。