【C# Xml】基底クラスをXmlSerializerで読み書き

  • Xml ファイルを読み込むときは、基底クラスを指定する
  • Xml ファイルを読み込んだ後は、拡張クラスとして扱いたい

こんな場面が多々あります。そんなときに使える方法です。

XMLファイルの読み書きに、XmlSerializer を使用します。クラスオブジェクトをXMLファイルに相互変換するイメージで使うことができます。

目次

XMLファイルと対応するクラス

今回は、以下の構成を例にします。基底クラスとしてUserXmlクラス、拡張クラスとしてAdministratorXml、EditorXml クラスを使用します。

基底クラス

基底クラスであるUserクラスのコードです。

重要なことは、基底クラスの属性( Attribute ) にXmlInclude を設定することです。パラメータに拡張クラスの型を指定します。対応させたいすべての拡張クラスを設定します。

using System.Xml.Serialization;

namespace XmlProject
{
    /// <summary>
    /// ユーザーXml
    /// </summary>
    [XmlInclude(typeof(AdministratorXml))]
    [XmlInclude(typeof(EditorXml))]
    public abstract class UserXml
    {

    }
}

今回はUserXmlを抽象クラスとしました。抽象クラスでなくても、これから説明する方法で読み書き可能です。

拡張クラス

AdministratorXml、EditorXml クラスは、UserXmlを継承したクラスです。

AdministratorXml のコード
namespace XmlProject
{
    /// <summary>
    /// 管理者Xml
    /// </summary>
    public class AdministratorXml : UserXml
    {
        /// <summary>ID</summary>
        public string? id;

        /// <summary>パスワード</summary>
        public string pass;

        /// <summary>年齢</summary>
        public int age;

        /// <summary>年齢表示判定</summary>
        public bool isViewAge;

        /// <summary>役職</summary>
        public string position;

        public AdministratorXml()
        {
            id = null;
            pass = "abc";
            age = 30;
            isViewAge = false;
            position = "未設定";
        }
    }
}
EditorXml のコード
namespace XmlProject
{
    /// <summary>
    /// 編集者Xml
    /// </summary>
    public class EditorXml : UserXml
    {
        /// <summary>ID</summary>
        public string? id;

        /// <summary>パスワード</summary>
        public string pass;

        /// <summary>画像編集許可判定</summary>
        public bool isEnabledEditPicture;

        public EditorXml() {
            id = null;
            pass = "abc";
            isEnabledEditPicture = false;
        }
    }
}

XMLファイルに書き込み

AdministratorXml クラスをUserクラスとして書き込みます。このようにXMLファイルを書くことで、読み込み時は、Userクラスとして読み込むことができます

XMLファイル保存クラス

XmlSerializerを使用した、Xml保存クラス であるXmlSaver は↓のようになります。

XmlSaver のコード
using System.Text;
using System.Xml.Serialization;

namespace XmlProject
{
    /// <summary>
    /// Xmlセーバー
    /// </summary>
    public class XmlSaver
    {
        /// <summary>
        /// XMLファイルに保存する
        /// </summary>
        /// <typeparam name="T">型</typeparam>
        /// <param name="xml">Xmlとして保存するクラス</param>
        /// <param name="filePath">保存するファイルパス</param>
        public static void Save<T>(T xml, string filePath)
        {
            //XmlSerializerオブジェクトを作成
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            //書き込むファイルを開く(UTF-8 BOM無し)
            using (StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false)))
            {
                //シリアル化し、XMLファイルに保存する
                serializer.Serialize(sw, xml);
            }
        }
    }
}

Xml 保存実行

XmlSaverを使用して、AdministratorXmlをUserXmlとして保存します。XmlSaverで保存する型をUserXmlとします

using XmlProject;

string filePath = Environment.CurrentDirectory + "/AdministratorXml.xml";

AdministratorXml administratorXml = new AdministratorXml();
administratorXml.id = "abc";
administratorXml.pass = "abc";
administratorXml.age = 78;
administratorXml.isViewAge = true;
XmlSaver.Save<UserXml>(administratorXml, filePath);

実行した結果、UserXmlとして保存されました。

  • 2行目のタグの名前がUserXmlとなっています。
  • 5行目にxsi;type = “AdministratorXml” が属性があります。型がAdministratorXmlであることを表します。

XMLファイルの読み込み

先ほど保存したものをUserXml クラスの型( 基底クラスの型 )を指定して読み込みます。読み込んだものはAdministratorXml クラスの型( 拡張クラスの型 ) として扱うことができます。

XMLファイル読み込みクラス

XmlSerializerを使用してXMLファイルを読み込むXmlLoader クラスは↓のようになります。

XmlLoaderのコード
using System.Text;
using System.Xml.Serialization;

namespace XmlProject
{
    /// <summary>
    /// Xmlローダー
    /// </summary>
    internal class XmlLoader
    {
        // XMLファイルをロードする
        public static T Load<T>(string path)
        {
            //XmlSerializerオブジェクトを作成
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            //読み込むファイルを開く
            using (StreamReader sr = new StreamReader(path, new UTF8Encoding(false)))
            {
                //XMLファイルから読み込み、逆シリアル化する
                T t = (T?)serializer.Deserialize(sr) ?? throw new Exception();
                return t;
            }
        }
    }
}

Xml読み込み実行

XmlLoader を使用して、先ほど保存したXMLファイルを読み込みます。XmlLoaderで、UserXmlクラス( 基底クラス )の型を指定します

コードは、UserXmlで読み込んだ後、UserXmlクラスの拡張クラスの型を出力しています。

using XmlProject;

Type[] userTypeTable = new Type[]
{
    typeof(AdministratorXml),
    typeof(EditorXml)
};

string filePath = Environment.CurrentDirectory + "/AdministratorXml.xml";


UserXml userXml = XmlLoader.Load<UserXml>(filePath);

foreach (Type t in userTypeTable)
{
    if (t == userXml.GetType())
    {
        Console.Write("UserXml Type = " + t.Name);
    }
}

このコードを実行した結果、型の名前がAdministratorXmlと出力されました。AdministratorXmlとして扱うことができます。

読み込んだUserXmlクラスのオブジェクトは、AdministratorXmlクラスに型変換することで、AdministratorXmlクラスのオブジェクトとして扱うことができます。

まとめ

C# Xml において、拡張クラスをXmlSerializerで読み書きというテーマで書きました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次