連載

.NETで簡単XML

第11回 オブジェクトをXMLでシリアライズ(3)

株式会社ピーデー 川俣 晶
2003/11/22

 これを呼び出す側のサンプル・プログラムは以下のようになる。

Private Sub serializeSample()
  Dim person1 As Adult = New Adult
  person1.Name = "山田太郎"
  person1.CompanyName = "山田商事"

  Dim person2 As Adult = New Adult
  person2.Name = "山田二郎"
  person2.CompanyName = "山田飯店"

  Dim person3 As Child = New Child
  person3.Name = "山田三郎"
  person3.SchoolName = "山田学園"

  Dim persons As New Persons
  persons.SetPersons(person1, person2, person3)

  Dim serializer As XmlSerializer = New XmlSerializer(GetType(Persons))
  Dim stream As FileStream = New FileStream("c:\sample.xml", FileMode.Create)
  Try
    serializer.Serialize(stream, persons)
  Finally
    stream.Close()
  End Try
End Sub

Private Sub deserializeSample()
  Dim serializer As XmlSerializer = New XmlSerializer(GetType(Persons))
  Dim persons As Persons
  Dim stream As FileStream = New FileStream("c:\sample.xml", FileMode.Open)
  Try
    persons = CType(serializer.Deserialize(stream), Persons)
  Finally
    stream.Close()
  End Try
  persons.Dump()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  serializeSample()
  deserializeSample()
End Sub
サンプル・プログラム1-2:シリアライズ/デシリアライズを行うプログラム(VB.NET版C#版

 これを実行すると、以下のような結果が得られる。

山田太郎
山田商事
山田二郎
山田飯店
山田三郎
山田学園

 このとき、生成されるXML文書は以下のようになる。

<?xml version="1.0"?>
<Persons xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <persons>
    <Adult>
      <Name>山田太郎</Name>
      <CompanyName>山田商事</CompanyName>
    </Adult>
    <Adult>
      <Name>山田二郎</Name>
      <CompanyName>山田飯店</CompanyName>
    </Adult>
    <Child>
      <Name>山田三郎</Name>
      <SchoolName>山田学園</SchoolName>
    </Child>
  </persons>
</Persons>
生成されるXML文書

 さて、プログラムの内容を説明しよう。ここでは、Personクラス型の配列をシリアライズする実例を見せるのがテーマである。しかし、この配列に、ただ単にPersonクラスのインスタンスへの参照を代入するだけなら、前回の例と何ら変わるところはない。そこで、Personクラスを継承した、AdultクラスとChildクラスが用意されている。この2つのクラスのインスタンスへの参照を配列に代入している。AdultクラスとChildクラスのインスタンスをPersonクラスのインスタンスとして扱うという手法はポリモーフィズムの考え方の1つであるといえるだろう。

 このサンプル・プログラムは、正常に実行できるが、そのポイントになるのは、配列に付加されたXmlArrayItem属性である。この属性は、プロパティ、フィールド、引数、戻り値に付加することができ、配列の要素の型として有効なものが何であるかをシリアライズ機能に示す役割を持つ。逆にいえば、シリアライズ機能以外には何の意味も持たないもので、この属性の有無はほかの機能には一切影響を与えない。それは、この配列にシリアライズできない型への参照を代入しても、それだけではエラーにならないということを意味する。シリアライズが行われる前にその要素が取り除かれるのであれば、シリアライズできない型への参照を代入することもできる。しかし、通常はそのようなトリッキーなことを行うべきではないだろう。

 さて、次に、XmlArrayItem属性が2つ書かれていることに注目していただきたい。ポリモーフィズムというテクニックの性質上、複数の種類のクラスが配列に代入される可能性がある。この目的でXmlArrayItem属性を付加する場合は、1つだけということはあり得ないだろう。複数の同じ属性を付ける構文も確認しておこう。

 次は、XmlArrayItem属性の引数に注目しよう。ここではTypeという名前付き引数に、型情報を渡している。型情報を取得するには、VB.NETではGetType関数を、C#ではtypeof演算子を使用する。これらは、System.Type型の型情報を持つオブジェクトへの参照を返す。.NET Frameworkの世界では、宣言された型には、すべてそれぞれに対応するこのようなオブジェクトが作成されていることを確認しておこう。

 もう1つ、重要なことを確認しておこう。XmlArrayItem属性は、プロパティ、フィールド、引数、戻り値に付加することができると書いたが、この中にクラスは含まれない。例えば、PersonクラスにXmlArrayItem属性を付けておくと、Personクラスの配列をシリアライズする場合に必ずXmlArrayItem属性で指定したクラスもシリアライズされるというような使い方はできない。XmlArrayItem属性は、必ずプロパティ、フィールド、引数、戻り値のいずれかに付ける必要がある。


 INDEX
  .NETで簡単XML
  第11回 オブジェクトをXMLでシリアライズ(3)
    1.派生クラスを含む配列のシリアライズ
  2.派生クラスを含む配列をシリアライズするプログラムの内容
    3.要素のシーケンスとしての配列のシリアライズ
    4.ArrayListオブジェクトのシリアライズ
    5.自作コレクションのシリアライズ
 
インデックス・ページヘ  「連載 :.NETで簡単XML」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間