Relaxer のバックアップ(No.8)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Relaxer へ行く。
- 1 (2006-06-29 (木) 15:40:07)
- 2 (2006-07-07 (金) 12:57:27)
- 3 (2006-07-12 (水) 18:47:24)
- 4 (2006-07-13 (木) 10:37:24)
- 5 (2006-07-21 (金) 19:39:22)
- 6 (2006-08-01 (火) 14:07:43)
- 7 (2006-11-08 (水) 12:17:47)
- 8 (2006-11-29 (水) 12:42:31)
- 9 (2007-01-09 (火) 11:35:26)
- 10 (2007-01-16 (火) 18:51:22)
- 11 (2007-01-17 (水) 10:50:54)
- 12 (2007-01-23 (火) 11:21:04)
- 13 (2007-01-29 (月) 17:26:33)
- 14 (2007-06-28 (木) 15:44:03)
- 15 (2007-07-26 (木) 14:09:09)
- 16 (2007-07-28 (土) 23:15:01)
- 17 (2007-10-20 (土) 02:48:18)
- 18 (2007-11-26 (月) 13:06:07)
- 19 (2012-11-23 (金) 04:37:40)
- 20 (2014-09-04 (木) 05:32:19)
- 21 (2015-12-24 (木) 18:49:10)
- 22 (2018-07-09 (月) 17:13:16)
Relaxer
編集者:Terai Atsuhiro
作成日:2003-09-25
更新日:2018-07-09 (月) 17:13:16
概要
このページには、MLに流れたRelaxer関連のニュースや、個人的によく使うオプションのサンプルなどを置いています。
Relaxerとは
Relaxerは、スキーマコンパイラ*1です。
- Relaxerは、「RELAX NGなどで定義されたXML文書」を操作するための「Javaクラス」を自動生成することが出来ます。
- Relaxerを使えば、XMLを操作するプログラムを作成するのに、繁雑なDOMプログラミングが不要になります。
- RelaxerはRELAX NGでモデル化されたXMLドキュメントのインフォセットを、Javaオブジェクトにマップします。そしてインフォセットのインスタンスである、XMLドキュメント、DOMツリーとJavaオブジェクトの相互変換を行うプログラムを自動生成します。
ニュースメモ
Relaxer関係のニュースを勝手にメモしています(ニュース過去ログ)。
- 2006-11-08
relax-users-j 03336 Re: objectVerifyオプション指定時のエラーについて
- 浅海氏、[ Relaxer Version 1.1b (20061108) ]をリリース
- http://www.relaxer.org/download/beta.zip
- objectVerifyオプションを指定して生成したJavaソースでコンパイルエラーが発生する
- Relax NGスキーマからW3C XML Schemaに変換する場合にemptyStringが生成される
- 浅海氏、[ Relaxer Version 1.1b (20061108) ]をリリース
- 2006-08-01
relax-users-j 03309 Re: relaxerで変換したW3C XML Schemaのuse属性
- 浅海氏、[ Relaxer Version 1.1b (20060724) ]をリリース
- 必須属性を含むRelax NGスキーマをW3C XML Schemaに変換すると、誤ったuse属性値がセットされる
- 浅海氏、[ Relaxer Version 1.1b (20060724) ]をリリース
事例紹介
以下の表は、あるライブラリを作成するためにRelaxerを用いた時のデータです。スキーマをRELAX NGで作成し(4000行程度)、Relaxerを使ってこれから全部で約17万行のJavaソースコードを生成しています。
具体的には、XSL-FOを生成するためのXSLTスタイルシートを編集するエディタを作る際、その入出力や、妥当性を検証するためのライブラリです。フォントの扱いなどは多少異なりますが、おおまかな要素の構造などは、FOの仕様に沿ったものとなっています。
ファイル数 | サイズ | 総行数 | コメント行 | 実行数 | 空行数 | コメント率 | |
合計 | 169 | 5291916 | 174370 | 77045 | 84804 | 12521 | |
平均 | 31313 | 1031 | 455 | 501 | 74 | 44.13% |
- 効率的にシステムを構築する
- 要素や属性が多い文書構造(重複する属性なども大量にある)のXMLファイルを扱うプログラムを考えたとき、これをDOMなどで実装するのはかなり大変です*2。Relaxerを使えば、スキーマから上記の表のあるような大量のソースコードを一気に自動生成することができます。
- XMLとJavaを簡単に繋げる
- Relaxerの生成するコードを利用すれば、DOMやSAXを使うより直感的に、XMLの読み書きや妥当性の検証などを行うことが出来ます。
- デザインパターンテンプレートの埋め込み
- factoryパターンや、visitorパターンなどのテンプレートをソースコードに埋め込み利用することができます。上記のライブラリでは、factoryパターンを利用して別途7000行程度のコードを追加し、スキーマだけでは検証出来ない妥当性のチェックなどを実装しています。
インストール
インストールはコマンドラインから行います。 Downloadから、relaxer-1.0.zip、もしくは最新のベータ版をダウンロードし、以下のようにインストーラを起動します。
java -jar relaxer-1.0.zip
本体を展開する場所と、バッチファイルを展開する場所、バッチファイルに記入するメモリオプションなどを入力します。Command directoryはPathの通っている場所を指定します。
[Configuration] Install directory = c:\relaxer Command directory = c:\cygwin\bin
インストールしたフォルダのパスにスペースなどが含まれる場合は、relaxer.batを以下のように(パスを""で括る)編集します。
java -jar "C:\Program Files\relaxer-beta\Relaxer.jar" %1 %2 %3
基本的な使い方
RELAX NGのスキーマを作って、これを以下のようにコンパイルするとJavaのソースファイルが生成されます。
relaxer test.rng
RELAX NGスキーマの書き方については、RelaxerユーザのためのRELAX NG入門や、正式版のrelaxer-1.0.zipに付属のサンプルスキーマを参考にしてください。
プロパティファイル
自作のスキーマをコンパイルする場合は、一々コマンドラインでオプションを入力してると大変なので、プロパティファイルを作っておきます。デフォルトでは、カレントフォルダにあるRelaxer.propertiesファイルが使用されます。任意のファイルを使用する場合は、以下のように指定します。
relaxer -properties:hogehoge.properties relax/hoge.rng
プロパティファイル例
#詳細出力 verbose=true #出力先 dir=./src/relaxer/jp/co/hoge/relaxer #validation=none #パッケージ java.package=jp.co.hoge.relaxer #各種デザインパターン #java.pattern.factory=true #java.pattern.visitor=true #java.pattern.composite=true #ネームスペースとDOMの使用 java.xml.element=true java.xml.namespace=true #<aaa>要素がHogeAaa.javaに java.name.class.prefix=Hoge
出力ディレクトリに同名のソースファイルがある場合でも、問答無用で上書きされてしまうので、注意が必要です。
Antタスク
- relax-users-j 03128 によると、RelaxerTaskが使用できるようです。
<target name="relaxer" depends="prepare"> <taskdef name="relaxer" classname="org.relaxer.Relaxer.ant.RelaxerTask"> <classpath refid="relaxer.jar.path"/> </taskdef> <relaxer srcdir="${src.dir}"/> </target>
- relax-users-j 03055を参考に、以下のようなタスクを作って利用しています。${build.src}、${relaxer.home}などのプロパティは環境に合わせて値を入力しておきます。このサンプルでは、出力ディレクトリ以外のRelaxerのオプションは、Relaxer.propertiesファイルに設定しています。OutOfMemoryErrorがでる場合は、javaタスクのmaxmemory="128m"を変更してみてください。このタスクの場合、バッチファイルを利用しないので、インストール時に指定したメモリサイズは適用されないことに注意してください。
<target name="prepare-src" depends="prepare"> <delete dir="${build.src}" /> <mkdir dir="${build.src}" /> <java jar="${relaxer.home}/Relaxer.jar" fork="true" maxmemory="128m"> <arg value="-dir:${build.src}/relaxer"/> <arg value="-properties:${basedir}/Relaxer.properties"/> <arg value="${src.dir}/relaxng/xslfo.rng"/> <classpath> <fileset dir="${relaxer.home}" includes="*.jar"/> </classpath> </java> <copy todir="${build.src}" filtering="yes"> <fileset dir="${src.dir}" excludes="**/*.bak" /> </copy> </target>
オプション
以下に、個人的によく使うオプションの使い方についてメモしておきます。
Tips
候補値
Relaxerが生成するクラスには、choice要素で指定した候補値が、public static final で埋め込まれます。これを使えば、値を直書きしてスペルミスすることも無くなりますし、入力補完を使って楽をすることもできます。
<optional> <attribute name="text-align"> <choice> <value type="NMTOKEN">auto</value> <value type="NMTOKEN">start</value> <value type="NMTOKEN">justify</value> </choice> </attribute> </optional>
public static final String TEXTALIGN_AUTO = "auto"; public static final String TEXTALIGN_START = "start"; public static final String TEXTALIGN_JUSTIFY = "justify";
Relax Core(+Namespace)からRELAX NGへの移行
Relax CoreからRELAX NGへ変換する方法はいろいろありますが、Relaxerで扱うことを考えると、お勧めは以下の方法です。
relaxer -properties:rng.properties -rng relax/fondoc.rxg
rng.propertiesファイルには出力ディレクトリを設定しているだけです。この例だと、./relax/fondoc.rngが生成され、上書きさてれしまう点に注意が必要です。
Ref1.javaなどのよく分からないクラスができたら、そのクラスの先頭付近にある要素をさがしだし、スキーマを修正します。無駄なネストや、重複が存在している場合が多いようです。
また、設定が間違っているのか、Relax namespaceがうまく反映されません。手で修正する必要があります。RELAX NGでのnamespaceについては、有修飾名(Qualified Name) の取扱いが参考になります。
- [relax-users-j 02822] 属性だけのdefine
現在は、名前空間をまたがった最適化を抑制しているので、このような形に なります。属性に関しては、もう少し最適化を効かした方がよい感じですね。
上のRelax namespaceがうまく反映されないのも関係あり?
メモ
- 0.17から1.0での変更点
- 以下のメソッドの名前が変わっています。スキーマから生成されるgetterなどと区別して、リフレクションしやすくするためでしょうか?
getContentCount()→rGerContentCount() getParentRNode()→rGerParentRNode() getXMLElement()→rGerXMLElement() getRNSContext()→rGerRNSContext()
- 以下のメソッドの名前が変わっています。スキーマから生成されるgetterなどと区別して、リフレクションしやすくするためでしょうか?
参考リンク
Relaxer関係のリンクです。