3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】xmlデータをデシリアライズする際のデータクラスや属性の定義方法

Posted at

概要

C#でxmlデータをデシリアライズする際の、データクラスの構成や属性定義についてのサンプルをまとめました。

属性名について

本稿で登場する、xmlのデシリアライズを行う際に必要な属性についてまとめました。

XmlRoot

XMLのルート要素名を指定できます。
クラスに適用します。

XmlElement

プロパティやフィールドの名前をXML要素にマップできます。

XmlAttribute

プロパティやフィールドの値をXML属性としてマップできます。

XmlArray

配列やリストをXML配列としてマップする際に使用します。

XmlArrayItem

XML配列内の各アイテムを指定する際に使用します。
XmlArray属性と組み合わせて使用します。

XmlInclude

XmlSerializerが派生クラスを認識できるようにするために使用されます。

XmlText

XMLの要素内のコンテンツテキストを指定する際に使用します。

デシリアライズの例

パターン1

XMLデータの構成の説明

要素名 説明
Sample ルート要素
HogeInfos
FugaInfos
PiyoInfos
要素数は必ず1つのみ
ItemInfo HogeInfos、FugaInfos、PiyoInfosの子要素
要素数は1つ以上

xmlデータ

<Sample>
  <HogeInfos>
    <ItemInfo Keyword="keyword1" Name="Name1" Value="Value1"/>
    <ItemInfo Keyword="keyword2" Name="Name2" Value="Value2"/>
  </HogeInfos>
  <FugaInfos>
    <ItemInfo Keyword="keyword3" Name="Name3" Value="Value3"/>
  </FugaInfos>
  <PiyoInfos>
    <ItemInfo Keyword="keyword4" Name="Name4" Value="Value4"/>
    <ItemInfo Keyword="keyword5" Name="Name5" Value="Value5"/>
    <ItemInfo Keyword="keyword6" Name="Name6" Value="Value6"/>
  </PiyoInfos>
</Sample>

データクラスの定義

定義例1

    [XmlRoot("Sample")]
    public class Sample
    {
        [XmlArray("HogeInfos")]
        [XmlArrayItem("ItemInfo")]
        public List<ItemInfo> HogeInfos { get; set; }

        [XmlArray("FugaInfos")]
        [XmlArrayItem("ItemInfo")]
        public List<ItemInfo> FugaInfos { get; set; }

        [XmlArray("PiyoInfos")]
        [XmlArrayItem("ItemInfo")]
        public List<ItemInfo> PiyoInfos { get; set; }
    }

    public class ItemInfo
    {
        [XmlAttribute("Keyword")]
        public string Keyword { get; set; }

        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlAttribute("Value")]
        public string Value { get; set; }
    }
  • XmlRoot属性に定義した名前はクラス名と同じなら、属性自体の記載を省けます。
  • XmlArray属性はプロパティ名が、XmlArrayItemは対応するクラス名が同じなら属性自体の記載を省けます。
  • XmlAttribute属性は記載を省くとプロパティの値がnullになってしまうので、記載する必要があります。

定義例2

    [XmlRoot("Sample")]
    public class Sample
    {
        [XmlElement("HogeInfos")]
        public HogeInfo HogeInfos { get; set; }

        [XmlElement("FugaInfos")]
        public FugaInfo FugaInfos { get; set; }

        [XmlElement("PiyoInfos")]
        public PiyoInfo PiyoInfos { get; set; }
    }

    public class HogeInfo
    {
        [XmlElement("ItemInfo")]
        public List<ItemInfo> ItemInfos { get; set; }
    }

    public class FugaInfo
    {
        [XmlElement("ItemInfo")]
        public List<ItemInfo> ItemInfos { get; set; }
    }

    public class PiyoInfo
    {
        [XmlElement("ItemInfo")]
        public List<ItemInfo> ItemInfos { get; set; }
    }
    
    public class ItemInfo
    {
        [XmlAttribute("Keyword")]
        public string Keyword { get; set; }

        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlAttribute("Value")]
        public string Value { get; set; }
    }
  • Sampleクラス内のXmlElement属性は、定義した名前とプロパティ名が同じなら、属性自体の記載を省けます。
  • HogeInfoFugaInfoPiyoInfoクラス内のXmlElement属性は、定義した名前とリストとなるクラス名が同じなら省けます。

デシリアライズ方法

        private Sample ReadXml(string path)
        {
            try
            {
                if (!File.Exists(path))
                {
                    // エラー処理
                }

                var xml = XElement.Load(path);
                string xmlText = xml.ToString();

                var serializer = new XmlSerializer(typeof(Sample));
                var deserializedData = (Sample)serializer.Deserialize(new StringReader(xmlText));

                return deserializedData;
            }
            catch (Exception ex)
            {
                // エラー処理等
            }
        }

備考

データクラスの定義例1と2でデシリアライズ後のデータクラスの階層の構成は違いがありますが、どちらもデシリアライズできます。

パターン2

XMLデータの構成の説明

要素名 説明
Sample ルート要素
HogeData
FugaData
要素数は必ず1つのみ
Targets HogeData、FugaDataの子要素
要素数は1つ以上
Keyword Targetsの子要素
要素数は1つ以上

xmlデータ

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Sample version="">
	<HogeData>
		<Targets Value="あたい">
			<Keyword Text="もじ">AA</Keyword>
			<Keyword Text="モジ">BB</Keyword>
		</Targets>
		<Targets Value="アタイ">
			<Keyword Text="文字">CC</Keyword>
		</Targets>
	</HogeData>
	<FugaData>
		<Targets Value="値">
			<Keyword Text="moji">DD</Keyword>
		</Targets>
	</FugaData>
</Sample>

データクラス

定義例1

    [XmlRoot("Sample")]
    public class Sample
    {
        [XmlElement("HogeData")]
        public HogeData hogeData { get; set; }

        [XmlElement("FugaData")]
        public FugaData FugaData { get; set; }
    }

    public class DataTypeBase
    {
        [XmlElement("Targets")]
        public List<Targets> Targets { get; set; }
    }

    public class HogeData : DataTypeBase
    {
    }

    public class FugaData : DataTypeBase
    {
    }

    public class Targets
    {
        [XmlAttribute("Value")]
        public string Value { get; set; }

        [XmlElement("Keyword")]
        public List<Keyword> Keywords { get; set; }
    }

    public class Keyword
    {
        [XmlAttribute("Text")]
        public string Text { get; set; }

        [XmlText]
        public string Value { get; set; }
    }

定義例2

    [XmlRoot("Sample")]
    public class Sample
    {
        [XmlElement("HogeData")]
        public HogeData hogeData { get; set; }

        [XmlElement("FugaData")]
        public FugaData FugaData { get; set; }
    }

    [XmlInclude(typeof(HogeData))]
    [XmlInclude(typeof(FugaData))]
    public abstract class DataTypeBase
    {
        [XmlElement("Targets")]
        public List<Targets> Targets { get; set; }
    }

    public class HogeData : DataTypeBase
    {
    }

    public class FugaData : DataTypeBase
    {
    }

    [XmlInclude(typeof(Targets))]
    public class Targets
    {
        [XmlAttribute("Value")]
        public string Value { get; set; }

        [XmlElement("Keyword")]
        public List<Keyword> Keywords { get; set; }
    }

    public class Keyword
    {
        [XmlAttribute("Text")]
        public string Text { get; set; }

        [XmlText]
        public string Value { get; set; }
    }

デシリアライズ方法

こちらと同様。

補足

シリアライズについて

デシリアライズ後のクラスを使用して、以下のようにシリアライズもできます。

    var xml = XElement.Load(path);
    string xmlText = xml.ToString();

    // デシリアライズ
    var serializer = new XmlSerializer(typeof(Sample));
    var deserializedData = (Sample)serializer.Deserialize(new StringReader(xmlText));

    // シリアライズ
    serializer = new XmlSerializer(typeof(Sample));
    var writer = new StringWriter();
    serializer.Serialize(writer, deserializedData);
    xmlText = writer.ToString();  // xml形式の文字列が取得できる (デシリアライズ前と同様の文字列)

終わりに

それぞれの属性の細かな動きはまだ学習中ですが、単純なxmlのデシリアライズの際に役に立てればと思い記載しました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?