XmlSerializer – XMLファイルの読み書き

技術的な話題です。

System.Xml.Serialization.XmlSerializer を調査した。仕様は以下(全てでは無い)。

  • パブリックメンバであるフィールドとプロパティだけ
  • 読み込み、あるいは書き込みしか許可されていないプロパティは対象外
  • クラスには規定のコンストラクタが必須

この仕様だとシリアライズするためだけにメンバをパブリックにしたり必要ないアクセス権を公開したりしなければならず、自分的に却下!
これなら XML を DOM として読み書きするコードを自分で書いた方がマシ!

でも DOM の操作は結構面倒(nao4u でXML扱っているソフトウェアは DOM を操作しています)

そこで別の解は無いかとググってみると「DataContractSerializer」なるものを発見!
DataContractSerializer の仕様は以下(全てでは無い)。

  • シリアライズするクラスには[DataContract]属性を付ける
  • シリアライズするメンバには[DataMember]属性を付ける
  • [DataMember]属性が適用されていないメンバはシリアライズされない
  • [DataMember]属性が適用されていれば、privateなメンバでもシリアライズ可能
  • System.Xml.Serialization.XmlSerializerではシリアライズできないDictionaryクラスなどもシリアライズ可能
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;

namespace XmlSerializer
{
	/// XMLシリアライザ(静的クラス)
	public static class XmlSerializer<T>
	{
		/// XMLファイルの読み込み
		public static T Load(string filepath)
		{
			if(!File.Exists(filepath))
			{
				throw new ArgumentException("do not exist file");
			}

			var dcs = new DataContractSerializer(typeof(T));

			using (var xr = XmlReader.Create(filepath))
			{
				return (T)dcs.ReadObject(xr);
			}
		}

		/// XMLファイルに保存
		public static void Save(string filepath, T obj)
		{
			if (!File.Exists(filepath))
			{
				Directory.CreateDirectory(Path.GetDirectoryName(filepath));
			}

			var dcs = new DataContractSerializer(typeof(T));

			var xws = new XmlWriterSettings()
			{
				Encoding = new UTF8Encoding(false),
				Indent = true,
				IndentChars = "  ",
				NewLineHandling = NewLineHandling.None,
			};

			using (var xw = XmlWriter.Create(filepath, xws))
			{
				dcs.WriteObject(xw, obj);
			}
		}
	}
}

ただ、上位互換が気になります。プログラムをバージョンアップした場合に読み書きできるか、上手いことやらないと痛い目を見そうです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です