RelaxNGCC チュートリアル1

 RelaxNGCCは、RELAX NGスキーマを読んでJavaのソースコードを生成するツールです。生成されたソースコードは、そのスキーマに合ったXML文書を読んだときにユーザがスキーマに埋め込んでおいた動作をします。

 次のようなXML文書を考えます。これは2001年8月15日のサッカーの試合(日本対オーストラリア)での、日本代表のスターティングメンバーです。

<?xml version="1.0" encoding="shift_jis"?>
<team>
  <player number="1" ><name>川口能活</name></player>
  <player number="3" ><name>松田直樹</name></player>
  <player number="4" ><name>森岡隆三</name></player>
  <player number="16"><name>中田浩二</name></player>
  <player number="21"><name>波戸康広</name></player>
  <player number="14"><name>伊東輝悦</name></player>
  <player number="17"><name>戸田和幸</name></player>
  <player number="6" ><name>服部年弘</name></player>
  <player number="8" ><name>森島寛晃</name></player>
  <player number="9" ><name>柳沢敦</name></player>
  <player number="22"><name>鈴木隆行</name></player>
</team>

 ここには team エレメントの中に player エレメントがあり、player エレメントは number アトリビュートと name エレメントを持っています。この構造を記述するRELAX NG文法は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
  xmlns:c="http://www.xml.gr.jp/xmlns/relaxngcc">
<start c:class="sample1">

<element name="team">
  <oneOrMore>
    <element name="player">
      <attribute name="number">
        <data type="positiveInteger" c:alias="number"/> [1]
        <c:java>System.out.println(number);</c:java> [2]
      </attribute>
      <element name="name">
        <text c:alias="name"/> [3]
        <c:java>System.out.println(name);</c:java> [4]
      </element>
    </element>
  </oneOrMore>
</element>

</start>

</grammar>

 RelaxNGCC固有の追加情報(namespace prefix "c" がついています)は赤いところです。まず、numberアトリビュートの中身をしめすdataエレメント[1]に注目してください。ここにaliasアトリビュートがついています。aliasアトリビュートは、XML文書中のデータをJavaからアクセスできるようにするためのものです。こうすることでnumberという変数でこのdataエレメント(XMLインスタンスではnumberアトリビュートの値)の値にアクセスできます。同様に、nameエレメントの中身[3]にもnameという名前でアクセスできるようにしています。

 次に、"java"エレメント([2],[4])です。これは、XML文書を読んだときに実行するJavaコード断片を記述したものです。ここでは文書の中身を確認するためにSystem.outに出力しています。

 さらに、これら全体はoneOrMore内に入っているので、コードはplayerエレメントの個数だけ繰り返し実行されることになります。

 では、これをRelaxNGCCにかけてみます。

$ java -classpath msv.jar;relaxngcc.jar relaxngcc.RelaxNGCC sample1.rxm

そうすると、カレントディレクトリにJavaのソースファイルが出力されます。これの一部は次のようになっています。完全なものはここにあります。

import java.math.BigInteger;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import relaxngcc.runtime.NGCCPlainHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;

class sample1 extends NGCCPlainHandler {
public static final String DEFAULT_NSURI = "";
private int _ngcc_current_state;
private String name;
private String number;
(中略)
public void enterElement(String uri,String localname,String qname) throws SAXException
{
if(_ngcc_current_state==1) {
if(localname.equals("player") && uri.equals(DEFAULT_NSURI)) {
_ngcc_current_state=7;
processAttribute();

}
(中略)
public void text(String value) throws SAXException
{
if(_ngcc_current_state==4) {
{
name=value;System.out.println(name);
_ngcc_current_state=3;

}
}

else if(_ngcc_current_state==6) {
{
number=value;System.out.println(number);
_ngcc_current_state=5;

}
}
}
}
これをコンパイルして実行すると、
$ javac -classpath msv.jar:relaxngcc.jar:. sample1.java
$ java -classpath msv.jar:relaxngcc.jar:. sample1.java sample1.xml
1
川口能活
3
松田直樹
4
森岡隆三
16
中田浩二
21
波戸康広
14
伊東輝悦
17
戸田和幸
6
服部年弘
8
森島寛晃
9
柳沢敦
22
鈴木隆行

となります。

 このように最も基本的なRelaxNGCCの使い方は、dataまたはtextエレメントにaliasアトリビュートを使って名前を付け、javaエレメントでコードを埋め込むことです。javaエレメント内からはJavaでできるあらゆることが可能なので、外部のライブラリを呼んだりデータベースにアクセスしたりといったことも簡単です。


RelaxNGCC home