連載

.NETで簡単XML

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

株式会社ピーデー 川俣 晶
2004/02/18
Page1 Page2 Page3 Page4


Back Issue
1
XML超入門
2
プログラムでXML文書を作成する
3
XML文書を読み書きするプログラムの作成
4
DOM(Document Object Model)

5

DOMとXPath

6

.NETプログラムでXSLTスクリプトを使う

7

VS.NETでXML Schemaを活用する(作成編)
8
VS.NETでXML Schemaを活用する(動作編)
9
オブジェクトをXMLでシリアライズ(1)
10
オブジェクトをXMLでシリアライズ(2)
11
オブジェクトをXMLでシリアライズ(3)
12 オブジェクトをXMLでシリアライズ(4)
13 オブジェクトをXMLでシリアライズ(5)

 前回は、SoapFormatterクラスを使ったシリアライズについて解説を行った。今回は引き続きSoapFormatterクラスについて解説した後、XML Webサービス経由で使われるシリアライズについて説明する。

ISerializableインターフェイスを用いたシリアライズ制御

 SoapFormatterクラスでシリアライズを行う際、シリアライズする内容をきめ細かく制御する方法がある。それは、ISerializableインターフェイス(System.Runtime.Serialization名前空間)を実装する方法である。このインターフェイスが実装されていると、SoapFormatterクラスはオブジェクト内のフィールドを勝手に拾い上げてシリアライズする代わりに、このインターフェイスのメソッドを呼び出してくれる。よって、このメソッド内で、必要な情報だけをシリアライズ対象に指定するようにコーディングすれば、思いどおりにシリアライズ結果を制御することができるわけである。NonSerialized属性を付けていないフィールドはすべてシリアライズされる、という大ざっぱな方法が好ましくない場合は、この方法を使うことができる。

 それでは、ISerializableインターフェイスを実装したサンプル・コードを以下に示す(ただし、前回の最初のサンプル・ソースとの相違点のみ)。シリアライズ方法の制御は、シリアライズされる側のクラスで行われるため、シリアライズする側のコードに変更はない。以下は、シリアライズされる側のクラスのソース・コードである。

<Serializable()> _
Public Class Person
  Implements ISerializable

  Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) Implements ISerializable.GetObjectData
    info.AddValue("Name", m_name)
    info.AddValue("Address", m_address)
    info.AddValue("Age", Age)
  End Sub

  Public Sub New()
  End Sub

  Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    m_name = info.GetString("Name")
    m_address = info.GetString("Address")
    Age = info.GetInt32("Age")
  End Sub

  Private m_name As String = "未設定"
  Private m_address As String = "未設定"
  Public Age As Integer = 0
  Private m_temporaryID As String = "未設定"
  Public Property Name() As String
    Get
      Return m_name
    End Get
    Set(ByVal Value As String)
      m_name = Value
  End Set
  End Property
  Public ReadOnly Property Address() As String
    Get
      Return m_address
    End Get
  End Property
  Public Sub SetTemporaryID(ByVal temporaryID As String)
    m_temporaryID = temporaryID
  End Sub
  Public Sub Dump()
    System.Diagnostics.Trace.WriteLine(m_name)
    System.Diagnostics.Trace.WriteLine(m_address)
    System.Diagnostics.Trace.WriteLine(Age)
    System.Diagnostics.Trace.WriteLine(m_temporaryID)
  End Sub
End Class
サンプル・プログラム1:ISerializableインターフェイスを実装したPersonクラス(VB.NET版C#版

 これを実行すると、統合開発環境の出力ウィンドウに以下のような出力が得られる。

山田太郎
未設定
17
未設定
サンプル・プログラム1の出力結果
Personオブジェクトがシリアライズ/デシリアライズされる際に統合開発環境の出力ウィンドウに出力される結果。

 また、シリアライズの結果として以下のような内容のXMLファイルが「c:\sample.xml」に生成される。

<SOAP-ENV:Envelope xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:Person id="ref-1" xmlns:a1=
"http://schemas.microsoft.com/clr/nsassem/
VBSample019/VBSample019%2C%20Version%3D1.0.1437.20064%2C%20
Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Name id="ref-3">山田太郎</Name>
<Address id="ref-4">未設定</Address>
<Age>17</Age>
</a1:Person>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
サンプル・プログラム1で生成されたXML文書

 ここで注目していただきたいことは、クラスの定義と、実際に出力された内容が一致していないことである。前の例(SoapFormatterクラスによって生成されたXML文書)であれば、すべてのフィールドが、そのフィールドの名前の要素によって出力されていた。しかし、ここでは要素名は、フィールド名と一致しておらず(例えばフィールドm_nameが、Nameという要素名で出力されている)、しかも、すべてのフィールドが出力されているわけではない。

 このような結果の相違は、もちろん、すでに述べたとおり、ISerializableインターフェイスを実装したことによって変化した出来事である。しかし、ただ単にISerializableインターフェイスを実装するだけでは、不十分であることにも注意しなければならない。実際、前回の最初のサンプル(サンプル・プログラム1-2:SoapFormatterクラスによりシリアライズするPersonクラス)のソース・コードと比較して、このクラスにはISerializableインターフェイスを実装するためのメソッドが1つ(GetObjectDataメソッド)と、さらにコンストラクタが2つ増えている。


 INDEX
  .NETで簡単XML
  第14回 オブジェクトをXMLでシリアライズ(6)
  1.ISerializableインターフェイスを用いたシリアライズ制御
    2.ISerializableインターフェイスを使ったクラスの継承
    3.XML Webサービス経由で使われるシリアライズの種類
    4.XmlSerializerを使ってSOAP形式でシリアライズする方法
 
インデックス・ページヘ  「連載 :.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 記事ランキング

本日 月間