バックグラウンド
プロジェクトを作成/開くことができるデスクトップアプリケーションを開発しています(ビジュアルスタジオを考えてください)。このようなプロジェクト オブジェクトを XML ファイル (.csproj と考えてください) に保持し、そのプロジェクト オブジェクトを XML ファイルから読み込む必要があります。
目標
- クラス MyProject を XML ファイルに保存 / XML ファイルからロード
- 人間が読める XML (手動で編集するのは良くありませんが、いくつかのタスクを簡素化できます)
- 他の言語/アプリから解析できる有効な XML:
<?xml version="1.1" encoding="utf-8"?>
ファイルは、任意のカルチャのユーザー定義文字列がここで終了する可能性があるため、XML 宣言で始まります。したがって、エンコーディングは重要です。有効な XML ファイルには xml 宣言が必要ですか?も参照してください。- クラスの名前空間を指定できます (例: 経由
DataContractAttribute.NameSpace
)
Q: オブジェクトを読み取り可能で有効な XML ファイルに永続化する最良の方法は何ですか?
XML を作成するには多くの方法がありますが、私にとっては [DataContract] 属性が適しているように思えます。これにより、オブジェクトへの単純なシリアル化と逆シリアル化が可能になるからです (目標 1)。XmlTextWriter を使用する場合、Formatting.Indented
目標 2 を解決する を指定することもできます。ただし、XML 宣言を作成できません。
編集:受け入れられた回答に基づく解決策
XmlTextWriter
行き止まりだったのを使っては、受け付けませんXmlWriterSettings
。XML を記述する (間違った/悪い) 方法が多すぎます。目的の設定で使用XmlWriter.Create(..)
すると、宣言を含む人間が読める XML が生成されます。作成されたインスタンスは、 のような内部クラスですWellFormedXmlWriter
。コード:
public static void Store<T>(string filename, T obj)
where T : class
{
XmlWriterSettings settings = new XmlWriterSettings()
{
Indent = true, // human readable
OmitXmlDeclaration = false, // don't omit the encoding
Encoding = Encoding.UTF8
};
using (var xmlwriter = XmlWriter.Create(filename, settings))
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
ser.WriteObject(xmlwriter, obj);
}
}
public static T Load<T>(string filename)
where T : class
{
using (var xmlReader = XmlReader.Create(filename))
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
return (T)ser.ReadObject(xmlReader, true);
}
}