連載

.NETで簡単XML

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

株式会社ピーデー 川俣 晶
2003/12/23
Page1 Page2 Page3

xsd.exeによるスキーマからソース生成

 シリアライズするプログラムを作成するプログラマーにスキーマを渡す、ということが可能なら逆も可能である。つまり、自分がシリアライズするプログラムを作成する側で、デシリアライズするプログラムを作成するプログラマーからスキーマを渡される、という状況である。その場合には、どのように対処すればよいだろうか。

 スキーマを見ながら、それに適合するXML文書を出力するプログラムをDOMなどを使って記述することはできるが、これはシリアライズとはいえない。完全にスキーマに適合するクラスを手動で記述することもできるが、それよりももっと楽な方法がある。xsd.exeを使うと、スキーマからソース・コードを自動生成することができるのである。

 これを行うには、xsd.exeの引数に、スキーマのファイルを指定し、クラスを生成するオプション「/c」と、使用言語を指定するオプション「/l:」を指定する。「/c」は、「/classes」の省略形である。「/l:」は「/language:」の略で、その後にプログラム言語を示す略語を付ける。Visual Basic .NETなら「vb」、C#なら「cs」である。例えば、前の例で生成したschema0.xsdファイルから、ソース・コードを生成するには、以下のようなコマンドラインを入力する。

Visual Basic .NETのソース・コードを生成する場合:

xsd schema0.xsd /c /l:vb

C#のソース・コードを生成する場合:


xsd schema0.xsd /c /l:cs
xsd.exeによるスキーマからのソース・コードの生成

 Visual Basic .NETの場合、schema0.vbという名前のファイルが、C#の場合、schema0.csという名前のファイルが生成される。その内容は以下のようなものになる。

'------------------------------------------------------------------------------
' <autogenerated>
'     This code was generated by a tool.
'     Runtime Version: 1.1.4322.573
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </autogenerated>
'------------------------------------------------------------------------------


Option Strict Off
Option Explicit On

Imports System.Xml.Serialization

'
'このソース コードは xsd によって自動生成されました。Version=1.1.4322.573 です。
'


'<remarks/>
<System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=true)>  _
Public Class Person

  '<remarks/>
  Public Name As String

  '<remarks/>
  Public Age As Integer
End Class
サンプル・プログラム2:xsd.exeによりスキーマから自動作成したソース・ファイル(VB.NET版C#版

 これらのソース・ファイルを自作プログラムのプロジェクトに取り込んで使えば、必要とされるXML文書のシリアライズが容易になる。

 しかし、このソース・コードを見て分かるとおり、生成されたPersonクラスの定義は、元のPersonクラスの定義とは似ても似つかないものになっている。スキーマに直接対応するクラスを生成することは、元のクラスを再現することとイコールではない。その理由は、スキーマが作成されるとき、実際には、元のクラスのほんの一部の情報だけがスキーマに書き込まれるにすぎないからだ。また、publicなフィールドが付加されていることは、アクセサ(プロパティのGetメソッドやSetメソッド)を付けるという常識からすれば不適切に見えるかもしれない。そのあたりは、手動で対処する必要がある。しかし、手動で対処するとしても、ゼロから書き起こすよりは手間の節約になるだろう。

 なお、生成されたコードについて、1点だけ補足説明を加えておこう。Visual Basic .NETの場合の生成結果の中で、属性の名前付き引数のNamespaceが、“[Namespace]”とカギ括弧でくくられて表記されている。見慣れない表記だと思ったプログラマーも多いかもしれないが、これは「エスケープ識別子」と呼ばれるもので、予約語と同じつづりの識別子を使用可能にするものである。Visual Basic .NETでは「Namespace」という名前は予約語(言語仕様書ではキーワード)であるが、クラス・ライブラリでこの名前を使うように定義されているので、エスケープ識別子として記述しているものと思われる。しかし、前々回のサンプル・ソースを見るとわかるように、エスケープ識別子として記述していなくても動作する。

既存スキーマからクラスを生成する

 スキーマからクラスを生成する機能は、シリアライズ/デシリアライズと関係なく、ただ単にXML文書を読み込むだけの場合にも役に立つ。XML文書を読み込んでクラスに適切に値を設定するプログラムを作成する手間が、格段に減らせるのである。

 ここでは、XML Webサービスのインターフェイスを記述するWeb Service Definition Language(WSDL)のスキーマからxsd.exeを使用してソース・コードを生成してみよう。スキーマをここから入手しているとして話を続ける。

 WSDLのスキーマがwsdl.xsdというファイル名でカレント・ディレクトリにあるとすると、以下のようなコマンドでソース・コードを生成できる。

Visual Basic .NETのソース・コードを生成する場合:

xsd wsdl.xsd /c /l:vb

C#のソース・コードを生成する場合:

xsd wsdl.xsd /c /l:cs
WSDLのスキーマからのソース・コードの生成

 Visual Basic .NETの場合、wsdl.vbという名前のファイルが、C#の場合、wsdl.csという名前のファイルが生成される。その内容は以下のようなものになる。これらを真剣に読んで理解する必要はない。このようなものが生成でき、それによって手間を節約できるということを実感するために、ざっと眺めていただければよい。

サンプル:スキーマから自動生成されたソース・ファイル(長いため、別ページで表示)

 さて、この機能は、一見するとXML文書を扱う万能の救世主のようにも見える。XMLを用いた新しい主要な言語(数が多いのですべて紹介することは到底できないが、いくつか紹介すると、例えば、WSDLなどWebサービス系の言語はもちろん、日本において旅行業EDIの仕様を標準化するTravelXMLや、まだWorking Draftではあるが、XHTMLをXML Schemaのスキーマで提供するModularization of XHTML in XML Schemaなどがある)は、XML Schemaによるスキーマが用意されていることが多く、それを使ってソースを生成すれば、かなり手間が省けることになる。しかし、実際に筆者が試してみたところ、xsd.exeで扱えないスキーマがいくつも見つかった。この理由は、主に2つに分類できた。

 1つは、XML Schemaの勧告版ではなく、それより古い版を基にしたスキーマがしばしば見つかったことである。古い版では名前空間のURIが違うため、xsd.exeでは完全に正しいスキーマとは認識されずにエラーとなる。

 もう1つは、xsd.exeがスキーマのエラーとして扱うケースである。こちらの方は、スキーマの誤りであるか、それともxsd.exeの機能制限などの問題であるか、子細にスキーマの内容を調べなければ正確なことは何もいえないが、xsd.exeで扱えないスキーマに遭遇したという経験だけはここに書き添えておく。xsd.exeでスキーマからソースを生成する場合は、事前にそれが可能か確認した方がよいだろう。


 INDEX
  .NETで簡単XML
  第12回 オブジェクトをXMLでシリアライズ(4)
    1.xsd.exeによるスキーマの自動生成
  2.スキーマからソースの生成
    3.XmlRoot属性やXmlType属性とスキーマの関係
 
インデックス・ページヘ  「連載 :.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 記事ランキング

本日 月間