連載 役に立つXMLツール集(3)
Castorでデータバインディングに挑戦しよう
XMLプログラミングでは、DOMやSAXといったAPIを使用すると単調なコードを繰り返し書くことになり生産性が上がらないものだ。本連載では開発者が“楽をする”ために役立つXML関連ツールを紹介していく。(編集局) |
www.netpotlet.com
原田洋子
2004/1/8
主な内容 Castorの概要 Castorの入手とセットアップ 開発手順 スキーマの作成 スキーマのコンパイル 読み込みアプリケーションの作成 読み込みアプリケーションの実行 文書操作アプリケーションの作成 文書操作アプリケーションの実行 まとめ&サンプル・ダウンロード |
前回のJAXBに引き続き、XMLモデルからオブジェクトモデルへのマッピングを行う、データバインディングツールを紹介します。今回、取り上げるのはCastorです。
CastorはExolab Groupが開発したオープンソースのデータバインディングツールで、無償で利用できます。この分野では最もよく使われているツールといえるでしょう。また、CastorはXML−オブジェクト間のマッピングだけではなく、SQLやLDAPとオブジェクトのマッピングにも対応しています。今回の記事ではSQL/LADPは取り上げませんが、このようなところまでカバーしている多機能な点も人気の一因のようです。
現在、Castorが対象にしているスキーマ言語はW3C XML Schemaのみです。すでにあるDTDの定義についてはW3C XML Schemaに変換するコンバータが付属していますので、Castorでも利用できます。ただし、洗練されたツールではないようで、変換できないDTDが多々ありました。変換できない場合は前回、紹介したTrangを利用するといいでしょう。Trangなら、どのようなDTDやRELAX NGからでもW3C XML Schemaによる定義を生成できるので、スキーマ言語による制約から解放されます。また、W3C XML SchemaやRELAX NGなどのスキーマ言語による構造を定義していなくても、CastorはXMLインスタンスやJavaクラス定義からほかのモデルへのマッピングも行えるようになっています。
このように多機能で広く使われているCastorですが、独自APIが採用されているのみで、データバインディングのためのAPIであるJAXB仕様には対応していません。現時点ではJAXB APIへの対応について特にアナウンスはないので、当面、Castor独自APIのまま開発が進められるものと思われます。
これから紹介するサンプルはJAXBとの違いを理解しやすくするため、前回と同じものをCastor用に修正して説明していきます。本記事のプログラムは
- J2SDK 1.4.1_06
- Castor 0.9.5.1
- Eclipse 2.1.2/2.1.x Translations
を使用し、Linux上で動作を確認しています。
Castorは次のURLからダウンロードできます。
http://www.castor.org/download.html
2003年12月時点で最新版は0.9.5.2ですが、このバージョンはW3C XML SchemaからJavaのソースコードを生成するSourceGeneratorがうまく動かなかったため、本記事では1つ前のバージョンである0.9.5.1をftp://ftp.exolab.org/pub/castor/から取得して使いました。
必要なアーカイブは
- ドキュメントを含むすべてが同梱されているcastor-0.9.5.1.tgz(zip)
- ドキュメントを除く、すべての機能を含むcastor-0.9.5.1.jar
- XML、オブジェクト間のマッピング機能のみのcastor-0.9.5.1-xml.jar
のどれか1つです。tgzあるいはzip形式を取得した場合は適当なディレクトリに展開しておきます。
Eclipseのセットアップ
本記事はEclipse上で開発/実行することを前提にしますので、クラスパスのセットアップなどはEclipse上で行います 注。
※注 Eclipseの詳細には触れませんので、@ITのEclipse関連記事などを参照してください。また、前回の記事に掲載している操作画面も参考にしてください。 |
1. Javaプロジェクト作成(例:streamプロジェクト)
ファイル → 新規 → プロジェクト → Java(左ペイン) →
Java プロジェクト(右ペイン) → 次へ → プロジェクト名(stream) → 終了
2. Javaのビルド・パス設定
パッケージ・エクスプローラーでプロジェクト(stream)選択 →
右クリック → プロパティー → Javaのビルド・パス(左ペイン) →
ライブラリー選択 → 外部 JAR の追加 →
castor-0.9.5.1-xml.jar(あるいは castor-0.9.5.1.jar)
アーカイブを追加する(画面)
3. フォルダ作成
ソース・フォルダ
パッケージ・エクスプローラーでプロジェクト(stream)選択 →
右クリック → 新規 → ソース・フォルダー → フォルダー名(src) → 終了
スキーマ用フォルダ
パッケージ・エクスプローラーでプロジェクト(stream)選択 →
右クリック → 新規 → フォルダー → フォルダー名(schemas) → 終了
XML文書用フォルダ
パッケージ・エクスプローラーでプロジェクト(stream)選択 →
右クリック → 新規 → フォルダー → フォルダー名(docs) → 終了
CastorはXMLインスタンスやJavaオブジェクトからもマッピングを始められますが、やはり構造を定義したスキーマから始めるのが基本ですから、図1に示す手順で開発を進めます。これは前回のJAXBによる開発方法を説明した図1とまったく同じです。詳細は前回の説明を参照してください。
図1 データバインディングツールを利用した開発手順 |
最初に文書構造をスキーマ言語を使って定義します。冒頭で触れたようにJAXBのサンプルと同じものを使いますから、スキーマも前回記事のリスト3のkeyboard.xsdを利用します。ただし、このままではCastorが解釈できない定義があるので、その部分を修正しました。
本来は
<key size="large"> |
<key> |
のように属性でも、要素でも同じ名前でtypeやsizeを指定できるようにしたいのですが、そのような定義を正しく解釈してJavaのコードを生成できるデータバインディングツールはあまり多くありません。次回に紹介する予定のRelaxerはできるのですが、残念ながらCastorにはできません。
Castorはこの問題を回避するために、バインディングファイル(通常、binding.xml)により、外部から詳細を指示する方法が用意されています。バインディングファイルでは同名の要素名、属性名の解決のほか、要素や属性をデフォルト以外のJavaクラス/インターフェイスへマッピングしたい場合にも利用します。本記事ではスキーマを修正しても問題にはならないので、Castorがコードを生成できるように、次の2種類のルールでXML文書を記述することにしました。
<key attrSize="large"> |
<key> |
このサンプルで利用するXML文書はリスト1のkeyboard1.xml、リスト2のkeyboard2.xmlの2種類、スキーマ定義がリスト3のkeyboard.xsdです。
1 <?xml version="1.0" encoding="UTF-8"?> |
リスト1 keyboard1.xml |
1 <?xml version="1.0" encoding="EUC-JP"?> |
リスト2 keyboard2.xml |
1 <?xml version="1.0" encoding="UTF-8"?> |
リスト3 keyboard.xsd |
CastorのコンパイラはSourceGeneratorと呼ばれるツールで、同名のクラスがその機能を提供しています。実行は前回のJAXB同様、Antを利用するほか、Castorプラグインを使う方法もあります。
Castorプラグインは次のURLから取得します。
http://xdoclipse.sourceforge.net/
このプラグインをEclipseに組み込んで再起動した後、拡張子がxsdのファイルを選択し、右クリックすると、図2に示すように“Generate Castor XML Sources ...”メニューが表示されます。このメニューを選択すると、図3に示す設定ウィンドウが開くので、ここでパッケージ名などを指定し、OKボタンを押すとJavaクラスが生成されます。
図2 Castorプラグイン(Generate Castor XML Sources ...) |
図3 Castorプラグインの設定(クリックで拡大します) |
本記事ではリスト4のビルドファイルを用意し、Antを実行しました。このとき図4のディレクトリ構成になっていることを想定しています。
SourceGenerator実行時に指定できる主な引数は表1のようになっています。ほかのオプションなど詳細はCastor付属のドキュメント「doc/sourcegen.html」、あるいは「doc/SourceGeneratorUser.pdf」にありますので参照してください。また、継承させるクラスを指定する、XML namespacesをパッケージに対応させる、といった操作はプロパティ「castorbuilder.properties」で設定できます。
|
|||||||||||||||||||||||||||
表1 主なSourceGeneratorの引数 |
図4 streamプロジェクトのディレクトリ構成(1) |
1 <project name="stream" default="castor" basedir="."> |
リスト4 build.xml(赤字部分は環境に合わせて変更してください) |
ビルドファイルを作成したら、設定して実行します(図5参照)。
実行 → 外部ツール → 外部ツール → Antビルド選択 → 新規 →
ロケーション/基本ディレクトリ設定 → 適用 → 実行
図5 Ant実行のための設定(クリックで拡大します) |
2回目以降のAnt実行は外部ツール実行ボタンをクリックするだけです。
ビルドが成功するとソース・フォルダにリスト4のpackageプロパティ(5行目)で指定したパッケージに所属するソースコードが自動生成されます。ここで、次のようにすると、自動生成されたソースコードが表示されるとともに、コンパイルされます。
パッケージ・エクスプローラーでプロジェクト(stream)選択 →
右クリック → 最新表示
本記事の場合、表2のパッケージ、クラスが自動生成されます。
|
||||||||||||||||
表2 リスト3のkeyboard.xsdから生成されたクラス |
スキーマをコンパイルしてAPIが生成されたので、今度は簡単なアプリケーションを試してみます。ここでも前回のJAXBと比較しやすいように、XML文書を読み込むプログラムを同様のスタイルで作ってみます。アプリケーション作成時には自動生成されたAPIのほか、Castorが提供するAPIも使います。
リスト5がXML文書を読み込むCastorReaderクラスです。JAXB同様、CastorでもXML文書の読み込みをアンマーシャル(Unmarshal)といい、これを行うには、自動生成されたKeyboardクラスのunmarshalメソッドを使うか、org.exolab.castor.xml.Unmarshallerクラスを使います。
リスト5はパッケージcom.netpotlet.testに属するクラスとして定義しましたので、次のようにしてパッケージ/クラスを作ります。
パッケージ・エクスプローラーでソース・フォルダー(src)選択 →
右クリック → 新規 → パッケージ →
パッケージ名(com.netpotlet.test) → 終了
パッケージ・エクスプローラーでパッケージ(com.netpotlet.test)選択 →
右クリック → 新規 → クラス → クラス名(CastorReader) → 終了
1 package com.netpotlet.test; |
リスト5 CastorReader.java |
XML文書の読み込みを行うアプリケーションを実行してみましょう。このアプリケーションはXML文書を実行時の引数から取得するので、次のように設定、実行します(図6、7参照)。なお、XML文書は図4のdocsディレクトリに置いてあります。
実行 → 実行... → Javaアプリケーション → 新規 → メインタブ →
プロジェクト名(stream)/
メイン・クラス(com.netpotlet.test.CastorReader) →
引き数タブ → プログラム引き数(docs/keyboard1.xml) → 適用 → 実行
図6 実行アプリケーションの設定(クリックで拡大します) |
図7 実行時の引き数指定(クリックで拡大します) |
XML文書が正しく書けていれば図8のように出力されます。
図8 実行結果 |
JAXBで試したのと同様に、要素や属性を追加してXML文書を出力するアプリケーションも試してみましょう。リスト6のCastorCreatorがそのためのクラスです。CastorでもJAXB同様、XML文書の出力をマーシャル(Marshal)といい、これを行うには自動生成されたKeyboardクラスのmarshalメソッドを使うか、org.exolab.castor.xml.Marshallerクラスを使います。両者の違いですが、デフォルトの設定でよい場合はKeyboardクラスのmarshalメソッドを、マーシャル時にXML文書のエンコードを指定するなどの操作を行いたい場合はMarshallerを使います。このサンプルではMarshallerを使い、出力を加工しました。
1 package com.netpotlet.test; |
リスト6 CastorCreator.java |
マッピングファイル
リスト6のCastorCreatorは30〜32行目でマッピングファイルを取得し、Marshallerにセットしています。マッピングファイルは、JavaクラスをどのようにXML文書にマップするかを詳細に指定するために利用するファイルです。拡張子で分かるようにXML文書です。CastorにはオブジェクトモデルからXMLモデルへのマッピング機能があると説明しましたが、そこで使われるのがマッピングファイルです。
このサンプルはXMLモデルからスタートしているので、マッピングファイルは必須ではありませんが、今回は出力を加工する目的で利用しました。マッピングファイルを使わない場合、ソースコード生成の元になったスキーマに従った構造でXML文書が出力されます。このサンプルはバインディングファイルを使わず、Castor用にスキーマを修正したので、属性のattrSize、attrTypeもそのまま出力されます。これではJAXBの出力と同じになりませんのでマッピング機能を利用し、最終的に同じ結果が得られるようにしてみました。
ここで利用したマッピングファイルがリスト7のmapping.xmlです。自動生成されたクラスと比較すれば何をしているのか分かると思います。特に16〜18行目に注目してください。ここではLabelクラスのインスタンス変数attrTypeをXML文書では属性typeにマップするように指定しています。こうすると、スキーマを修正したにもかかわらず、修正前のスキーマが適用されているかのように表示できます。
1 <mapping> |
リスト7 mapping.xml |
プロパティファイル
Castorはデフォルトでは出力するXML文書のインデントを行いません。改行やインデントは見た目にはきれいですが、データ的には
終了タグ、改行、スペース、スペース、スペース、スペース、開始タグ
のようになり、XML文書のサイズが大きくなるほどに、改行やインデントが占める容量を無視できなくなるためです。JAXBではインデントの制御をプログラム内で行いましたが、Castorはプロパティファイルで指定します。そのためのプロパティがリスト8のcastor.propertiesです。castor.propertiesでさまざまな詳細設定の指定が可能ですが、ひな型はソースコード一式の中のcastor-0.9.5.1/src/main/org/exolab/castor/castor.propertiesにあるので、ひととおり眺めておくといいでしょう。
# THE CASTOR PROPERTIES FILE |
リスト8 castor.properties |
以上のソース、マッピングファイル、プロパティファイルを含むstreamプロジェクトは最終的に図9に示す構成になっています。
図9 streamプロジェクトのディレクトリ構成(2) |
このアプリケーションも実行してみましょう。今度もXML文書を実行時の引数から取得するので、次のように設定、実行します。XML文書は図9のdocsディレクトリに置いてあります。
実行 → 実行... → Javaアプリケーション → 新規 → メインタブ →
プロジェクト名(stream)/
メイン・クラス(com.netpotlet.test.CastorCreator) →
引き数タブ → プログラム引き数(docs/keyboard2.xml) → 適用 → 実行
問題なく実行されれば、図10のように出力されます。
図10 実行結果 |
今回は、最も普及しているといっていいデータバインディングツールのCastorを取り上げましたが、いかがだったでしょうか。JAXBという標準仕様に対応していないものの、要素がクラスにマップされ、それを直接インスタンス化できるなど、分かりやすく使いやすいツールであることが分かったのではないでしょうか。実用的という表現が似合うツールです。長く現場で使われてきたので、デフォルトと詳細設定のアプローチなど、理にかなった方法が採り入れられているツールともいえるでしょう。
標準APIに非対応となってしまったのは、歴史的な経緯によるところが大きいと思われます。現時点ではJAXB仕様への対応は不明ですが、JAXB実装のソースコードが公開されるようになったり、ApacheサブプロジェクトでオープンソースのJAXB API実装JaxMeが開発されたりといった動きが出てきたので、Castorもいずれ対応を考えることになると思われます。
今回はXMLモデルとオブジェクトモデルのマッピング方法を説明しましたが、いずれJDOなどSQL関連機能を取り上げる予定です。
最後に、Castorの日本語による解説として次の書籍を紹介します。
- 『Javaオープンソース徹底攻略』
岡本隆史、吉田英嗣、山口卓也、樋山大輔 著
株式会社ソフト・リサーチ・センター ISBN4-88373-190-1
今回使用したプログラムやファイル類は以下からダウンロードできます。
- stream.zip(50Kbytes)
Windows環境で利用される場合、euc-jpをWindows-31Jなど適当なエンコーディングに変更してください。また、日本語を含むファイルはEUC-JPになっていますので、あらかじめ文字コードを変えてから利用されるといいでしょう。
◇
次回はRelaxerを取り上げる予定です。お楽しみに。(次回に続く)
======== my confessions ======== やってしまいました(^^;; 。前回の記事ですが、「character」を「charactor」と信じこんだまま、最後まで気付かず公開してしまいました。スミマセン。今回の記事では何事もなかったかのように「character」になっています。前回のJAXBと比較して読まれる場合は、charactor → characterと読み替えていただければ幸いです。なおプログラムの動作上、問題はありません。(苦笑) |
■関連記事
・SEのためのXML
Schema入門
・XMLテクニック集
・Javaで実現するDOM/SAXプログラミング
「連載 役に立つXMLツール集」 |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|