連載 役に立つXMLツール集(4)
Relaxerでデータバインディングに挑戦しよう

XMLプログラミングでは、DOMやSAXといったAPIを使用すると単調なコードを繰り返し書くことになり生産性が上がらないものだ。本連載では開発者が“楽をする”ために役立つXML関連ツールを紹介していく。(編集局)

www.netpotlet.com
原田洋子
2004/2/4

Relaxerの概要

主な内容
Relaxerの概要
Relaxerの入手とセットアップ
開発手順
スキーマの作成
スキーマのコンパイル
読み込みアプリケーションの作成
読み込みアプリケーションの実行
文書操作アプリケーションの作成
文書操作アプリケーションの実行
まとめ&サンプル・ダウンロード

 前回のCastorはいかがだったでしょうか。数あるツールのほとんどが輸入モノという昨今ですが、今回取り上げるデータバインディングツールは日本発の技術、Relaxerです。

 Relaxerは浅海智晴氏が開発したデータバインディングツールで、前回のCastor同様、オープンソース、無償で利用できるツールです。日本発のツールなので、日本語の資料や情報が充実していて、わざわざ英語のドキュメントを読む必要はありません。例えば、@ITにも「Relaxerで実現するJava開発の新プロセス」という、開発者である浅海氏の記事がありますが、このほか、メーリングリストや書籍、技術資料なども日本語で大丈夫です。

 Relaxerはデータバインディングツールとしての機能であるXML/オブジェクト間のモデルマッピングを行うばかりではなく、オブジェクト指向の世界ではおなじみのデザインパターンのうち、いくつかのパターンを構成するクラスを自動生成する機能もあります。また、Castorにも同様の機能はありますが、RelaxerにもデータベースへアクセスするためのO/Rマッピング機能もあります。

 このように、日本語でよい、機能が豊富といった理由から国内にはかなりの利用者がいるツールがRelaxerです。

 Relaxerが対象にしているスキーマ言語はRELAX Core/RELAX NGが基本 ですが、DTDにも対応しています。また、定義のないXMLインスタンスからもオブジェクトへマッピングできるようになっています。オプションを指定すると、マッピング時にRELAX NGやクラス定義からDTDを自動生成してくれるので、DTDから移行したばかりでも想定どおりの文書定義になったかどうかをチェックできます。

※注
現在RELAXにはRELAX Core(リラックスコア)とRELAX NG(リラクシング)という2種類のスキーマ言語があります。RELAX Coreは1つ前の世代に当たるもので、基本機能を提供しています。その後、OASISで標準化が行われていたTREX(Tree Regular Expressions for XML)と統合され、新たにOASISで標準化が進められることになったのがRELAX NGです。RELAX NGは2003年にISO国際標準規格として正式に認められました
いまでは、RELAX NGで文書定義を行うのが一般的です。なお、RELAX NG日本語チュートリアルがありますので参考にしてください。

 RelaxerはCastor同様、独自APIが採用されているのみで、データバインディングのための標準APIであるJAXB仕様には直接対応していません。ただし、JAXBへのマッピング機能があるので、RelaxerからJAXB APIを使えます。

 では、今回も実際に動かしてみましょう。JAXB、Castorとの違いを理解しやすくするため、前回と同じサンプルを使います。本記事のプログラムは

  • J2SDK 1.4.1_06
  • Relaxer 1.1b(20040203)
  • Eclipse 2.1.2/2.1.x Translations

を使用し、Linux上で動作を確認しています。

Relaxerの入手とセットアップ

 Relaxerは次のURLからダウンロードできます。

  http://www.relaxer.org/

 2004年1月時点で最新のリリース版は1.0ですが、このバージョンにはやや不具合があったため、本記事は1.1b(20040203)を使って動作を確認しました。

 Relaxerは単体で実行できるアーカイブのほか、Relaxer Eclipseプラグインもリリースされています。それぞれ、インストールは次のように行います。

Relaxer単体のインストール

 http://www.relaxer.org/download/beta.zipを入手したら、アーカイブを適当なディレクトリで展開します。展開したディレクトリにsetupクラスがあるので、これを実行してインストールします。

# mkdir tmp
# cd tmp
# unzip beta.zip
# java setup
Install directory [default: /usr/local/lib/relaxer]:
Command directory [default: /usr/local/bin]:
Java memory size option [default: -Xmx128M]:

[Configuration]
Install directory = /usr/local/lib/relaxer
Command directory = /usr/local/bin
Java memory size option = -Xmx128M

Type "yes" to install, "no" to re-enter, "exit" to exit
> yes
Extract archives...
Generate script...
  script = /usr/local/bin/relaxer
Done.
コンソール1 単体のインストール例(黄字は入力個所、↓はリターンです。)


Relaxer Eclipseプラグインのインストール

 プラグインのインストール方法は更新マネージャを利用してインストールするか、org.relaxer.eclipse_0.1.0.jarをダウンロードして、pluginディレクトリに展開するかのどちらかでインストールします。


Eclipseの詳細には触れませんので、@ITのEclipse関連記事などを参照してください。また、第2回で紹介したJAXBの記事に掲載している操作画面も参考にしてください。

 更新マネージャを利用する場合、Eclipseを起動し次のようにします。

1. ヘルプ → ソフトウェア更新 → 更新マネージャ(画面) →
  フィーチャーの更新 → 右クリック → 新規 →
  サイト・ブックマーク(画面) →
  新規更新サイト・ブックマーク(画面)

   名前:RelaxerPlugin
   URL:http://www.relaxer.org/eclipse/site/
   ブックマーク・タイプ:Eclipse更新サイト

  → 終了

2. フィーチャーの更新 → Relaxer Feature 0.1.0 選択(画面)
  → プレビュー の「すぐにインストール」をクリック
  → フィーチャー・インストール(画面) → 次へ
  → フィーチャー・ライセンス
  → 「使用条件の条項に同意します」をチェック(画面)
  → 次へ → インストール・ロケーション → 終了 → フィーチャーの検査
  → インストール → Eclipse再起動


 アーカイブをダウンロードした場合は次のようにします。

# cd /usr/local/eclipse/plugin
  (Eclipseをインストールしたディレクトリにあるpluginディレクトリ)
# mkdir org.relaxer.eclipse_0.1.0
# cd org.relaxer.eclipse_0.1.0
# jar xfv /somewhere/org.relaxer.eclipse_0.1.0.jar
コンソール2 Eclipseプラグインのインストール例(黄字は入力個所です)

 以上でインストール作業は終わりです。インストールされたRelaxerのバージョンを確認したい場合は次のようにします。

 ウィンドウ → 設定 → Relaxer 画面

※注
メモリ容量が少ないなど、非力なマシンで動かす場合、Eclipseが落ちやすいので、ここで表示されるウィンドウでFull build、Auto build、Increment buildの3つをfalseに指定するといいでしょう。falseを指定した場合、ビルドはパッケージごとに手動で行います。


Eclipseのセットアップ

インストールできたら、アプリケーション作成の準備やRelaxerによるソースコードの生成/コンパイルが自動的に実行されるようにする設定を行います。

1. Javaプロジェクト(gulf)の作成
 ファイル → 新規 → プロジェクト → Java(左ペイン) →
 Java プロジェクト(右ペイン) → 次へ → プロジェクト名(gulf) → 終了

2. フォルダ作成
 ソースフォルダ
 パッケージ・エクスプローラーでプロジェクト(gulf)選択 → 右クリック →
 新規 → ソース・フォルダー → フォルダー名(src) → 終了

 XML文書用フォルダ
 パッケージ・エクスプローラーでプロジェクト(gulf)選択 → 右クリック →
 新規 → フォルダー → フォルダー名(docs) → 終了

3. パッケージ作成
 パッケージ・エクスプローラーでソース・フォルダー(src)選択 →
 右クリック → 新規 → パッケージ →
 パッケージ名(com.netpotlet.boat) → 終了

4. Relaxerの機能を有効にする
 パッケージ・エクスプローラーでプロジェクト(gulf)選択 → 右クリック →
 Relaxer → Relaxer Enable(画面

 あるいは、

 パッケージ・エクスプローラーでプロジェクト(gulf)選択 → 右クリック →
 プロパティー → Relaxer → Relaxer builderをtrueにする → 適用 → OK

5. Relaxer環境の設定
 パッケージ・エクスプローラーでパッケージ(com.netpotlet.boat)選択 →
 右クリック → 新規 → その他 → Relaxer(左ぺイン) → RELAX NG
  → 次へ
 Relax NG SchemaウィンドウのFile nameをkeyboard.rngに修正(画面
 → 終了(画面

 環境を設定すると、デフォルトのスキーマ定義が作られます。

 ソースコード生成/コンパイル作業をビルドといいますが、自動ビルドが有効にしてあれば、終了をクリックすると同時にビルドが実行されます。自動でビルドされない設定にしてある場合、終了をクリックしてもソースコードは生成されていませんので、次のように手動でビルドします。

 パッケージ選択 → 右クリック → Relaxer → Build folder(画面

※注
筆者のマシンは非力なので、自動でビルドされない設定にしてあります。


開発手順

 RelaxerはCastor同様、XMLインスタンスからもマッピングを始められます。Castorのように、Javaオブジェクトからはマッピングできませんが、代わりに、DTDを生成してくれたり、データベース上に作られているテーブルからマッピングを始められたりします。しかし、やはりRelaxerも構造を定義したスキーマから始めるのが基本ですし、プラグインもこの方法に対応したツールですので、図1に示す手順で開発を進めます。この図はこれまでのJAXB、Castorによる開発方法を説明した図1とまったく同じです。詳細は本連載第2回の説明を参照してください。

 1 データバインディングツールを利用した開発手順


スキーマの作成

 最初に文書構造をスキーマ言語を使って定義します。冒頭で触れたようにJAXBのサンプルと同じものを使いますから、スキーマもJAXB、Castorの記事で使ったkeyboard.xsd相当のRELAX NGを作成します。ただし、Relaxerは

    <key size="large">
      <label type="control">space</label>
    </key>

    <key>
      <size>large</size>
      <label><type>control</type>space</label>
    </key>

のような定義でも問題なく動作します。つまり、typeやsizeのように同じ名前を要素と属性のどちらにも使っていいのです。そこで、このサンプルではリスト1のkeyboard1.xml、リスト2のkeyboard2.xmlの形式のXML文書で試すことにしました。リスト1と2のスキーマ定義はリスト3のkeyboard.rngです。

 XML文書はJAXBとCastorのサンプルと同様にdocsフォルダに置きます。Relaxerプラグインを利用する場合、スキーマファイルkeyboard.rngはcom.netpotlet.boatパッケージの中に置きます。これは、Relaxerプラグインがkeyboard.rngの変更をトリガにして、自動的に再ビルドを実行するように設計されているためです。Relaxerの環境設定を行ったときにデフォルトのスキーマ定義が作られるので、その定義内容をリスト3のように書き直します。Relaxerプラグインを使わずにAntでビルドする場合は、これまでどおりスキーマファイルをschemasフォルダに置けます。

 なお、本記事ではRELAX NG文法については触れませんので、冒頭で紹介した日本語チュートリアルや最後に紹介する書籍を参考にしてください。

 1 <?xml version="1.0" encoding="EUC-JP"?>
 2 <keyboard>
 3   <key>
 4     <label type="number" default="true">1</label>
 5     <label type="character">!</label>
 6   </key>
 7   <key>
 8     <label type="character">a</label>
 9   </key>
10   <key size="medium">
11     <label type="control">shift</label></key>
12   <key>
13     <label default="true"><type>number</type>2</label>
14     <label><type>character</type>@</label>
15   </key>
16   <key>
17     <size>large</size>
18     <label><type>control</type>space</label>
19   </key>
20 </keyboard>
リスト1 keyboard1.xml

 1 <?xml version="1.0" encoding="EUC-JP"?>
 2 <keyboard>
 3   <key>
 4     <label type="number" default="true">1</label>
 5     <label type="character">あ</label>
 6     <label type="character">い</label>
 7   </key>
 8   <key>
 9     <label type="number" default="true">2</label>
10     <label type="character">か</label>
11     <label type="character">A</label>
12   </key>
13   <key>
14     <label type="character" default="true">#</label>
15     <label type="control">記号</label>
16   </key>
17 </keyboard>
リスト2 keyboard2.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <grammar xmlns="http://relaxng.org/ns/structure/1.0"
 3  xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
 4  xmlns:relaxer="http://www.relaxer.org/xmlns/relaxer"
 5  xmlns:java="http://www.relaxer.org/xmlns/relaxer/java"
 6  xmlns:sql="http://www.relaxer.org/xmlns/relaxer/sql"
 7  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
 8  ns="">
 9
10   <start>
11     <element name="keyboard">
12       <zeroOrMore>
13         <element name="key">
14           <optional>
15             <ref name="size"/>
16           </optional>
17           <oneOrMore>
18             <ref name="label"/>
19           </oneOrMore>
20         </element>
21       </zeroOrMore>
22     </element>
23   </start>
24
25   <define name="size">
26     <choice>
27       <attribute name="size">
28         <ref name="size.list"/>
29       </attribute>
30       <element name="size">
31         <ref name="size.list"/>
32       </element>
33     </choice>
34   </define>
35
36   <define name="size.list">
37     <choice>
38       <value>large</value>
39       <value>medium</value>
40       <value>small</value>
41     </choice>
42   </define>
43     
44   <define name="label">
45     <element name="label">
46       <optional>
47         <attribute name="default">
48           <data type="boolean"
49                 datatypeLibrary="http://www.w3.org/2001/
XMLSchema-datatypes"/>
50         </attribute>
51       </optional>
52       <choice>
53         <attribute name="type">
54           <ref name="type.list"/>
55         </attribute>
56         <element name="type">
57           <ref name="type.list"/>
58         </element>
59       </choice>
60       <text/>
61     </element>
62   </define>
63
64   <define name="type.list">
65     <choice>
66       <value>control</value>
67       <value>character</value>
68       <value>number</value>
69     </choice>
70   </define>
71
72 </grammar>
リスト3 keyboard.rng


スキーマのコンパイル

 スキーマのコンパイルはRelaxerプラグインではビルドに相当します。Relaxerプラグインを自動的に再ビルドが実行されるように設定している場合、スキーマファイルとコンパイルのためのさまざまなオプションを指定するプロパティの修正・保存がトリガになって再ビルドされます。自動的に再ビルドしない場合は、「Relaxerの環境設定」で触れたようにパッケージのコンテキストメニューでビルドします。

 Relaxerプラグインによる再ビルドのトリガはデフォルトでは、スキーマファイルとプロパティの更新時に設定されていますが、スキーマファイルだけのような指定をプロパティで設定できるようになっています。変更したい場合はパッケージ・エクスプローラーからRelaxer.propertiesを開き、図2のプロパティエディタを表示させます。次に、エディタの下の方に並んでいるタブからRelaxerを選び、各プロパティでtrueやfalseを選びます。ここに表示されているプロパティには次の意味があります。

 relaxer.eclipse ----------- パッケージの自動ビルド有効/無効
 relaxer.eclipse.properties -- Relaxer.propertiesの変更をトリガにする
 relaxer.eclipse.schema ---- スキーマファイルの変更をトリガにする

 非力ではないマシンなら次のような設定にしておくと便利でしょう。

 relaxer.eclipse:true
 relaxer.eclipse.properties:true
 relaxer.eclipse.schema:false

2 Relaxer Eclipseプラグインのプロパティエディタ

 コマンドラインでコンパイルする、あるいはEclipse上でプラグインに頼らずコンパイルする場合、Relaxer単体をインストールしたときに作られるrelaxerコマンドやJARアーカイブを使います。例えば、図3のパッケージ・エクスプローラーに示すディレクトリ構成を想定すると、Antのビルドファイルはリスト4のようになります。このbuild.xmlはコンパイルのためのオプションを引数で指定しましたが、プロパティファイルで指定する方法もあります。指定できるパラメータはプラグインのプロパティエディタで指定可能なものと同じです。

3 プラグインを使わないスキーマコンパイルのための構成(クリックで拡大します)


 1 <?xml version="1.0"?>
 2 <project name="gulf" default="relaxer" basedir=".">
 3   <property name="relaxer.home"
               value="/usr/local/lib/relaxer"/>
 4   <property name="relaxer.jar"
               value="${relaxer.home}/Relaxer.jar"/>
 5   <property name="schema.dir" value="schemas"/>
 6   <property name="src.dir" value="src"/>
 7   <property name="schema" value="keyboard.rng"/>
 8   <property name="package" value="com.netpotlet.boat"/>
 9   <property name="javafile.dir"
               value="${src.dir}/com/netpotlet/boat"/>
10   
11   <target name="relaxer" depends="clean">
12     <java jar="${relaxer.jar}" fork="true">
13       <classpath>
14         <pathelement location="${relaxer.jar}"/>
15       </classpath>
16       <arg line="-dir:${src.dir} -dir.package"/>
17       <arg line="-validation:relax -java.package:com.
netpotlet.boat"/>
18       <arg line="${schema.dir}/${schema} -verbose" />
19     </java>
20   </target>
21   
22   <target name="clean">
23     <delete>
24       <fileset dir="${javafile.dir}" includes="**/*.java"/>
25     </delete>
26   </target>
27 </project>
リスト4 build.xml

 ビルドファイルを作成したら、次のように実行します。

 実行 → 外部ツール → 外部ツール → Antビルド選択 → 新規 →
 ロケーション/基本ディレクトリー設定 → 適用 → 実行

 2回目以降のAnt実行は外部ツール実行ボタンをクリックするだけです。

 どの方法でビルドを実行しても、表1に示すクラス、インターフェイスのソースコードが自動生成されます。ただし、Ant実行の場合、ソースコードが生成されるのみでコンパイルされていないので、次のようにしてコンパイルします。

 パッケージ・エクスプローラーでプロジェクト(gulf)選択 →
 右クリック → 最新表示

分類 生成されたクラス
パッケージ com.netpotlet.boat
インターフェイス ILabelMixed.java
ILabelMixedChoice.java
ISizeChoice.java
クラス Label.java
LabelType1.java
LabelType2.java
SizeSize1.java
SizeSize2.java
StartKeyboard.java
StartKeyboardKey.java
RString.java
ライブラリクラス RStack.java
UJAXP.java
URelaxer.java
表1 リスト3のkeyboard.rngから生成されたクラス

 では、次ページでいよいよRelaxerを使ったアプリケーションを作成してみましょう。(次ページへ続く

  1/2 後編 アプリケーションの作成

Index
連載 役に立つXMLツール集(4)
Relaxerでデータバインディングに挑戦しよう

前編 開発環境の準備
 Relaxerの概要
 Relaxerの入手とセットアップ
 開発手順
 スキーマの作成
 スキーマのコンパイル

 

後編 アプリケーションの作成
 読み込みアプリケーションの作成
 読み込みアプリケーションの実行
 文書操作アプリケーションの作成
 文書操作アプリケーションの実行
 まとめ&サンプル・ダウンロード

 

「連載 役に立つXMLツール集」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間