連載 役に立つXMLツール集(2)
JAXBでデータバインディングに挑戦しよう
XMLプログラミングでは、DOMやSAXといったAPIを使用すると単調なコードを繰り返し書くことになり生産性が上がらないものだ。本連載では開発者が“楽をする”ために役立つXML関連ツールを紹介していく。(編集局) |
www.netpotlet.com
原田洋子
2003/12/4
主な内容 JAXBの概要 JAXB参照実装の入手 セットアップ 開発手順 スキーマの作成 スキーマのコンパイル アプリケーション作成 アプリケーション実行 文書操作アプリケーション 文書操作アプリケーションの実行 まとめ&サンプル・ダウンロード |
前回「XMLをJavaにマップするデータバインディング」では、データバインディングがどのようなものかといった概要を説明しました。今回からは実際にデータバインディングツールを使い、どのようにしてXMLモデルからオブジェクトモデルへのマッピングを行うのかを見ていきましょう。
最初に取り上げるのはJAXB(The Java Architecture for XML Binding)です。JAXBはJavaの世界でいわゆる“標準”となるべく開発されているデータバインディングで、JavaのさまざまなAPI同様、仕様がJCP(Java Community Process)で決められ、参照実装(RI:Reference Implementation)がサン・マイクロシステムズからリリースされています。
このようなスタイルで開発され、リリースされるAPIやツールを使うときに注意しておきたいのは、その名前が仕様を指しているのか実装を意味するのかという点です。通常、サン・マイクロシステムズがリリースする参照実装の名前は仕様名と同じです。ただし、仕様と実装ではバージョン番号が違いますし、サン・マイクロシステムズ以外のベンダや団体が仕様の実装をリリースしていることもあります。例えば、JAXB 1.0はJSR-31という番号で検討されたAPI仕様ですが、この参照実装であるデータバインディングツールの最新版(2003年11月時点)はJAXB 1.0.2です。また、ApacheがリリースしているXercesはJAXP(Java API for XML Processing)を実装していますし、AxisはSAAJ(SOAP with Attachments API for Java)を実装しています。混乱のもとなので気を付けましょう。
本記事のプログラムは
を使用し、Linux上で動作を確認しています。
JAXBの参照実装はJWSDP(Java Web Services Developer Pack)に含まれています。JWSDPはJAXB、JAXP、SAAJ、JSFなど、XMLやXMLベースの各種ツールをひとまとめにしたパッケージで、次のURLからダウンロードできます。
http://java.sun.com/webservices/webservicespack.html
2003年11月時点で、JWSDPの最新版は1.3です。JWSDPのバージョンが上がっても、含まれる参照実装のすべてのバージョンが上がるわけではありません。上記Webページや各ツールのリリースノートにバージョンが明記されているので確認してください。
なお、JWSDPにはJAXBのバイナリのみが含まれていますが、JAXB Standard Implementation Projectからソースコードも入手できます。
JAXBを使う前に必要なセットアップをやっておきましょう。これ以降の説明ではJWSDPをインストールしたディレクトリをJWSDP_HOMEと呼び、$JWSDP_HOMEで参照することにします。
アーカイブの構成
JAXBの実行には次のアーカイブが必要です。
- $JWSDP_HOME/jaxb/lib/*
- $JWSDP_HOME/jwsdp-shared/lib/jax-qname.jar
- $JWSDP_HOME/jwsdp-shared/lib/namespace.jar
- $JWSDP_HOME/jwsdp-shared/lib/relaxngDatatype.jar
- $JWSDP_HOME/jwsdp-shared/lib/xsdlib.jar
- $JWSDP-HOME/jaxp/lib/endorsed/*
この中で、最後のjaxp/lib/endorsedにあるアーカイブは、
- $JAVA_HOME/jre/lib以下にendorsedディレクトリごとコピーする
- java.endorsed.dirsシステムプロパティに$JWSDP_HOME/jaxp/lib/endorsedをセットする
のどちらかの方法でセットアップします。本記事では1つ目の方法で行いました。そのほかのアーカイブはクラスパスにセットします。
Eclipseのセットアップ
本記事はEclipse上で開発/実行することを前提にしますので、クラスパスのセットアップはEclipse上で行います。ただし、Eclipseの詳細には触れませんので、@ITのEclipse関連記事「Eclipseを使おう!」などを参照してください。
1. Javaプロジェクト作成(例:valleyプロジェクト)
ファイル → 新規 → プロジェクト → (画面)
Java(左ペイン) → Javaプロジェクト(右ペイン) → 次へ → (画面)
プロジェクト名(valley)
→ 終了 (画面)
2. Javaのビルド・パス設定
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック →
プロパティー → (画面)
Javaのビルド・パス(左ペイン) → ライブラリー選択 →
外部JARの追加 → 次のアーカイブを追加する (画面)
jaxb-api.jar, jaxb-impl.jar, jaxb-libs, jax-qname.jar, namespace.jar
relaxngDatatype.jar, xsdlib.jar
3. フォルダ作成
ソースフォルダ
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック →
新規 → ソース・フォルダ → (画面)
フォルダ名(src) → 終了 (画面)
スキーマ用フォルダ
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック →
新規 → フォルダ → (画面)
フォルダ名(schemas) → 終了 (画面)
XML文書用フォルダ
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック →
新規 → フォルダ → (画面)
フォルダ名(docs) → 終了 (画面)
データバインディングを利用する場合、図1に示す手順で開発を進めます。最初に、XML文書の構造を定義したスキーマを作成します。次に、スキーマをコンパイルしますが、ここでXMLモデルからオブジェクトモデルへのマッピングが行われ、JavaのAPIが生成されます。マッピングというのはデータバインディングツールの主目的ですので、コンパイラは必ず用意されています。
Java APIが生成されたらアプリケーションを作成します。アプリケーションはスキーマから生成されたAPIのみでプログラミングできるツールと、ほかのAPIも必要なツールがあります。JAXBは後者です。アプリケーションの実行にはXML文書を入力にするケースが多いと思われますが、XML文書は必須ではありません。ダイナミックに生成し、XML文書として出力するアプリケーションも作れます。また、URLやストリームからXML文書を読み込んだり、DOM(Document Object Model)のインスタンスを取り込むことも可能です。
図1 データバインディングツールを利用した開発手順 |
とにかく最初に文書構造の定義を書かなくてはいけません。JAXBはXML Schemaがデフォルトのスキーマ言語ですが、試験実装という位置付けでRELAX NG、DTD、WSDLもサポートしています。XML Schemaについては
で連載記事が公開されているほか、次の書籍が出版されていますので、参考にしてください。
- 『XML Schema』エリック・バン・デル
ブリスト著 田村健人 ほか翻訳
オライリージャパン ISBN487311120X
JAXB 1.0が対応しているのはXML Schemaのサブセットです。非対応項目などの詳細については仕様書で確認してください。
さて、前回取り上げたキーボードの例でスキーマを考えてみましょう。データバインディングツールは要素名や属性名をクラス名、メソッド名、変数名にそのまま使いますので、ここで日本語を使ってしまうととてもプログラミングしにくくなりますので変更しました。また、構造についてももうちょっとブラッシュアップして、PCと携帯電話のキーボードを表現できるようにします。さらに、キーサイズとキータイプは属性でも要素でも指定できるようにしてみます。例えば、リスト1やリスト2のように書けるようにすることを考えます。
1 <?xml version="1.0" encoding="UTF-8"?> |
リスト1 keyboard1.xml |
1 <?xml version="1.0" encoding="EUC-JP"?> |
リスト2 keyboard2.xml |
すると、XML Schemaによる定義はリスト3のようになりますので、Eclipse上で次のようにしてkeyboard.xsdファイルを作成します。
4. スキーマファイルの作成
パッケージ・エクスプローラでフォルダ schemas選択 → 右クリック →
新規 → ファイル → (画面)
ファイル名 keyboard.xsd → 終了 (画面)
1 <?xml version="1.0" encoding="UTF-8"?> |
リスト3 keyboard.xsd (2004年6月15日訂正☆お詫び) |
☆お詫び 「XML & Web Services 会議室」でご指摘いただいたとおり、リスト3 keyboard.xsdには誤りがありましたので正しいものに修正しました。手違いにより動作確認前のスキーマを掲載していました。お詫び申し上げます。なお、サンプルコードのアーカイブvalley.zipには正しいkeyboard.xsdが含まれていましたので、修正の必要はありません。 |
JAXBのコンパイラはxjcと呼ばれています。xjcはコマンドラインで実行できるほか、Ant注のタスクXJCTaskも用意されています。AntはEclipse環境にも組み込まれていますので、ここではAntを使ってコンパイルします。
Antはmakeに代わるJavaで作られたビルドツールです。makeよりも機能が豊富で、プラットフォームに依存しないので、幅広く使われるようになったツールです。 |
リスト4のビルドファイルを次のように作成します。
5. ビルドファイルの作成
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック
→
新規 → ファイル → (画面)
ファイル名 build.xml → 終了 (画面)
( → リスト4のようにビルドファイルを作成 → 保存)
リスト4のbuild.xmlは図2のディレクトリ構成になっていることを想定しています。プロパティjwsdp.homeには環境に合わせて$JWSDP_HOMEの値に変更してください。また、XML Schema以外のスキーマ言語による定義を使う場合、XJCTask実行時のオプションで明示しなければなりません。XJCTaskの使用方法は$JWSDP_HOME/jaxb/docs/ant.htmlに説明がありますので参照してください。
図2 valleyプロジェクトのディレクトリ構成 |
1 <?xml version="1.0"?> |
リスト4 build.xml |
ビルドファイルを作成したら、設定して実行します。
6. ビルドの実行
実行 → 外部ツール → 外部ツール → (画面)
Antビルド選択 → 新規
→ (画面)
ロケーション/基本ディレクトリ設定(図3参照) → 適用 → 実行
図3 Ant実行のための設定(クリックで拡大します) |
2回目以降のAnt実行は図4に示す外部ツール実行ボタンをクリックするだけです。
図4 外部ツール実行ボタン |
ビルドが成功するとソースフォルダにリスト2のpackageプロパティ(7行目)で指定したパッケージとソースコードが自動生成されます。生成された時点ではEclipse上に表示されませんので、次のようにしてワークベンチを最新の状態にします。このとき自動生成されたソースコードがコンパイルされます。
7. ワークベンチの更新
パッケージ・エクスプローラでプロジェクト(valley)選択 → 右クリック
→
最新表示 (画面1、画面2)
JAXBはスキーマから3つのパッケージと各パッケージに属するクラス/インターフェイスを自動生成します。本記事のサンプルの場合、
- com.netpotlet.kayak:インターフェイス/ファクトリ
- com.netpotlet.kayak.impl:インターフェイスの実装
- com.netpotlet.kayak.impl.runtime:実行時に必要なAPI
が作られます。アプリケーションを作る場合、通常、com.netpotlet.kayakのインターフェイス/ファクトリとjavax.xml.bindパッケージのAPIを使います。
手始めに読み込みと検証を行うアプリケーションを作ってみたのが、リスト5 JaxbReaderクラスです。XML文書の読み込みはアンマーシャル(Unmarshal)といい、javax.xml.bind.Unmarshallerインターフェイスを使います(23〜24行目)。検証(バリデーション:Validation)が必要な場合はUnmarhallerのメソッドで指定します(22行目)。各要素や属性を取得するときに、スキーマから自動生成されたAPIを使います(31〜74行目)。
リスト5はパッケージcom.netpotlet.testに属するクラスとして定義しましたので、次のようにしてパッケージ/クラスを作ります。
8. パッケージ/クラスの作成
パッケージ・エクスプローラでソース・フォルダ(src)選択 → 右クリック
→
新規 → パッケージ → (画面)
パッケージ名(com.netpotlet.test) → 終了 (画面)
パッケージ・エクスプローラでパッケージ(com.netpotlet.test)選択 →
右クリック → 新規 → クラス → (画面)
クラス名(JaxbReader) → 終了 (画面)
1 package com.netpotlet.test; |
リスト5 JaxbReader.java |
XML文書の読み込みと検証を行うアプリケーションを実行してみましょう。このアプリケーションはJAXBが自動生成するAPIのパッケージ名とXML文書を実行時の引き数から取得するので、次のように設定、実行します(図5、6参照)。なお、XML文書は図2のdocsディレクトリに置いてあります。
9. アプリケーションの実行(JaxbReader)
実行 → 実行... → (画面)
Javaアプリケーション → 新規 → メインタブ
→
プロジェクト名(valley)/メイン・クラス(com.netpotlet.test.JaxbReader)
→ (画面)
引き数タブ → プログラム引き数(com.netpotlet.kayak docs/keyboard1.xml) → (画面)
適用 → 実行
図5 実行アプリケーションの設定(クリックで拡大します) |
図6 実行時の引き数指定 |
XML文書が正しく書けていれば次のように出力されます。
size: small [(default)type: number,
label: 1] [type: charactor, label: !] |
コンソール1 JaxbReaderの出力 |
ここで、例えばリスト1の5行目の開始/終了タグをlebelと書き換えて実行すると、次のように出力され検証をパスしなかったことが分かります。
DefaultValidationEventHandler: [ERROR]:
要素"lebel"はここには書けません。書けるのは: <label> |
コンソール2 JaxbReaderのエラー出力 |
要素や属性を追加してXML文書を出力するアプリケーションも試してみましょう。リスト6 JaxbCreatorクラスがそのような機能のあるサンプルです。XML文書の出力はマーシャル(Marshal)といい、javax.xml.bind.Marshallerインターフェイスを使います(21〜24行目)。新たに要素を作り出す場合には、JAXBがスキーマから自動生成したObjectFactoryクラスのcreate<要素名>()というメソッドを使います(50、61行目)。
1 package com.netpotlet.test; |
リスト6 JaxbCreator.java |
このアプリケーションも実行してみましょう。今度もJAXBが自動生成するAPIのパッケージ名とXML文書を実行時の引き数から取得するので、次のように設定、実行します。今度も、XML文書は図2のdocsディレクトリに置いてあります。
10. アプリケーションの実行(JaxbCreator)
実行 → 実行... →
Javaアプリケーション → 新規 → メインタブ →
プロジェクト名(valley)/メイン・クラス(com.netpotlet.test.JaxbCreator)
→ (画面)
引き数タブ → プログラム引き数(com.netpotlet.kayak docs/keyboard2.xml) → (画面)
適用 → 実行
問題なく実行されれば、次のように出力されます。
<?xml version="1.0" encoding="euc-jp" standalone="yes"?> |
コンソール3 JaxbCreatorの出力 |
なお、実行設定後に繰り返し実行する場合は図7に示すように実行ボタンをクリックするだけです。
図7 実行ボタン |
JAXBを使った簡単なアプリケーションを試してみましたが、いかがだったでしょうか。DOMやSAXでのプログラミング経験がある読者なら、かなりシンプルで理解しやすいコードになっていることが分かるでしょう。
特に、新規に要素を追加する場合、データバインディングツールを利用していると、定義にない構造は作れないようになっているので、検証にパスしない文書を作ってしまうことはありません。XSLTへの変換などの後処理がある場合は特に便利でしょう。
JAXBにはここで取り上げた以外にもさまざまな機能がありますので、ひととおりデータバインディングツールの説明をした後で、再度、取り上げる予定です。
今回のサンプルの動作確認はEclipseで行いましたが、最終的にvalleyプロジェクトは図8に示す構成になりました。
図8 valleyプロジェクトのディレクトリ構成(2) |
今回使用したプログラムやファイル類は以下からダウンロードできます。
- valley.zip(212Kbytes)
Windows環境で利用される場合、euc-jpをWindows-31Jなど適当なエンコーディングに変更してください。また、日本語を含むファイルはEUC-JPになっていますので、あらかじめ文字コードを変えてから利用されるといいでしょう。
◇
次回はCastorを取り上げる予定です。お楽しみに。(次回に続く)
======== my confessions ======== 「XML Schemaによる定義はこのようになります」とさらりといってのけましたが、実は、筆者はRELAX NGは書けるものの、XML Schemaは書けません (^^; 。そこで、XML Schemaがいるときはどうするかというと、取りあえずRELAX NGで定義を書いてtrangというツールで変換します。trangというのはXSLTをはじめ、数々の仕様やツールの作者としてXML分野で有名なJames Clark氏が作られた変換ツールです。Trangはhttp://thaiopensource.com/relaxng/trang.htmlからダウンロードできます。今回の記事で使用したソースコード一式にRELAX NGによる定義も入れておきましたので、XML Schemaによる定義と見比べてください。なぜ、RELAX NGなら書けるのか分かるのではと思います。 |
■関連記事
・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」の詳細も紹介する
|
|