連載 .NETで簡単XML 第14回 オブジェクトをXMLでシリアライズ(6)株式会社ピーデー 川俣 晶2004/02/18 |
|
|
XmlSerializerを使ってSOAP形式でシリアライズする方法
実は、XmlSerializerクラスは、SOAP形式でシリアライズする機能を持っている。といっても、SoapFormatterクラスと同等の機能を発揮できるというわけではない。最大の相違は、シリアライズされる対象(メンバ)である。SOAP形式を指定してシリアライズしても、XmlSerializerクラスはパブリック・フィールドとパブリック・プロパティのみを扱い、すべてのフィールドを扱うわけではない。
では実際に、XmlSerializerクラスでSOAP形式のシリアライズを行うサンプル・ソースを作成してみよう。
ソース・コードの先頭には以下のコードを追加しておく。
|
|
サンプル・プログラム6:XmlSerializerクラスでSOAP形式のシリアライズを行うサンプル・ソースの先頭に追加するコード(VB.NET版/C#版) |
シリアライズされる対象となるクラスは以下のとおりである。本当はほかのサンプル・ソースと同じクラスでもよいのだが、いくつかの属性についての解説を行いたいので、それを追加してある。
|
|
サンプル・プログラム7:XmlSerializerクラスでSOAP形式のシリアライズを行うPersonクラス(VB.NET版/C#版) |
以下はシリアライズ、デシリアライズを行うメソッドである。これまでの例にはなかったcreateSoapOverriderというメソッドが増えていることに注意していただきたい。
|
|
サンプル・プログラム8:XmlSerializerクラスでSOAP形式のシリアライズを行うメソッド(VB.NET版/C#版) |
これを実行すると、以下のような出力が得られる。
|
|
サンプル・プログラム8の出力結果 |
また、同時に以下のような内容のXMLファイルが「c:\sample.xml」に生成される。
|
|
サンプル・プログラム8で生成されるXML文書 |
ここで出力されているXML文書の内容も、SoapFormatterクラスを使ってシリアライズした場合と同じではないことが分かるだろう。しかし、xsi:type属性が付いているなど、確かにSOAP形式らしい部分がある。
ここで重要なのは、そのことよりも、どうやってXmlSerializerクラスにSOAP形式を扱うように命じられるかである。注目していただきたいのは、これまでただ単に、XmlSerializerクラスのインスタンスを作成していたのに対して、その処理が複雑化しているところである。この処理は、シリアライズとデシリアライズで2回必要とされるので、独立したcreateSoapOverriderというメソッドにまとめている。このメソッドで作成されたXmlSerializerクラスのインスタンスを使えば、SOAP形式でシリアライズされるわけである。
createSoapOverriderメソッドで使用されているSoapAttributeOverridesクラス(System.Xml.Serialization名前空間)は、シリアライズする方法をオーバーライドして置き換えるために使われるものである。これと似たものに、XmlAttributeOverridesクラス(System.Xml.Serialization名前空間)がある。これは、SOAP形式ではない通常の形式でオーバーライドするためのものである。
また、XmlTypeMappingクラス(System.Xml.Serialization名前空間)は、1つの型から別の型への割り当てを格納するクラスである。これは、エンコード済みのSOAP XMLとしてオブジェクトをシリアル化するときに使用するものである。
これらのクラスは、意味を完全に理解するとかなり大変なので、このような一連の流れで使うパターンとして覚えておくとよいだろう。
このサンプル・プログラムでは、もう1つ、別の話題を扱っている。シリアライズされるクラスの中に、SoapAttribute属性(System.Xml.Serialization名前空間)やSoapElement属性(System.Xml.Serialization名前空間)が書き込まれている。これらの属性は、すでに解説したシリアライズ内容をコントロールするためのXmlAttribute属性(System.Xml.Serialization名前空間)や、XmlElement属性(System.Xml.Serialization名前空間)と同様の機能を持っている。例えば、SoapAttribute属性を指定した「Age」は、シリアライズ時に属性として出力されていることが分かるだろう。ここで注意すべき点は、同じXmlSerializerクラスによってシリアライズする場合でも、SOAP形式を使う場合とそうではない場合で、異なる属性を使わねばならないことである。これは裏を返すと、シリアライズする形式が異なるときに、異なる条件でシリアライズを制御することが容易であることを意味する。例えば、同じフィールドに、SoapAttribute属性とXmlAttribute属性を付けて、それぞれに異なる引数を設定してもよい。
作成済みクラスのシリアライズ方法の変更
話は少しそれるが、SoapAttributeOverridesクラスを活用すると、ただ単にシリアライズをSOAP形式にするだけでなく、シリアライズ内容そのものを制御することができる。その例を参考までに取り上げておく。
それを行うには、先ほどのcreateSoapOverriderメソッドを変更する必要がある。変更した内容を以下に示す。
|
|
サンプル・プログラム9:SoapAttributeOverridesクラスを使ってシリアライズを制御するコード(VB.NET版/C#版) |
これを実行すると、以下のような出力が得られる。
|
|
サンプル・プログラム9の実行結果 |
また、以下のような内容のXMLファイルが「c:\sample.xml」に生成される。
|
|
サンプル・プログラム9で生成されるXML文書 |
見てのとおり、本来Ageという要素名で出力されるはずであった要素が、Nenreiという名前で出力されていることが分かるだろう。要素名の変更は、属性を使って実現できることをすでに紹介しているが、それとは機能性が異なっている。属性を使って要素名を変更することは、シリアライズされる側のクラスの変更によって実現できる。しかし、ここで行っている要素名の変更は、シリアライズする側の変更によって実現したものである。
この違いは極めて大きい。例えば、既存のクラス・ライブラリに含まれるクラスなど、ソース・コードを変更できないクラスのインスタンスをシリアライズするときに、要素名などを変更したいと思うことがあるかもしれない。そのような場合には、属性を使う方法では対処できず、ここで紹介しているようなオーバーライドという手段を取る必要がある。
具体的なコードを説明する。ここでポイントとなるのは、SoapElementAttributeクラスのインスタンスを作成し、登録しているところである。SoapElementAttributeクラスとは属性を実現するクラスであるが、ここでは属性ではなく通常のクラスとしてインスタンスを作成している。このクラスの役割は属性として使った場合と同じで、メンバが要素としてシリアライズされることを指定する。そして、コンストラクタの引数の文字列が要素名を示す。この属性は、SoapAttributesクラスのインスタンスのSoapElementプロパティに設定されることで、シリアライズを制御するオブジェクトに関連付けられる。そして、それをSoapAttributeOverridesクラスのAddメソッドで登録する。登録する際に「Age」という名前を指定することにより、この属性クラスのインスタンスは、Ageというフィールドに関連付けられることになる。
これらの一連の処理により、指定された属性が付加されているかのようにシリアライズ処理が行われるわけである。
さて、今回はここまでである。次回からは連載を締めくくるために、筆者なりのXMLプログラミングの定石(パターン)について書いてみたいと考えている。こういうケースではこのような技術を選択すると良い結果になった、というような筆者の経験に基づく話を予定している。この連載では、多くの技術を紹介したため、どれを使ったらよいか迷ってしまう、というような読者もいると思うので、それに対するフォローという意味合いもある。請うご期待である。
INDEX | ||
.NETで簡単XML | ||
第14回 オブジェクトをXMLでシリアライズ(6) | ||
1.ISerializableインターフェイスを用いたシリアライズ制御 | ||
2.ISerializableインターフェイスを使ったクラスの継承 | ||
3.XML Webサービス経由で使われるシリアライズの種類 | ||
4.XmlSerializerを使ってSOAP形式でシリアライズする方法 | ||
「連載 :.NETで簡単XML」 |
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|