RelaxNGCC チュートリアル1Tutorial 1

 RelaxNGCCは、RELAX NGスキーマを読んでJavaのソースコードを生成するツールです。生成されたソースコードは、そのスキーマに合ったXML文書を読んだときにユーザがスキーマに埋め込んでおいた動作をします。 RelaxNGCC is a tool for generating Java source code from a given RELAX NG grammar. By embedding code fragments in the grammar, you can take appropriate actions while parsing valid XML documents against the grammar.

 次のようなXML文書を考えます。これは2001年8月15日のサッカーの試合(日本対オーストラリア)での、日本代表のスターティングメンバーです。 For first example, suppose the following XML instance. This is a list of Japan national team members for the soccer game, which was held on Aug 15, 2001 against Australia.


<?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>
<?xml version="1.0" encoding="utf-8"?>
<team>
  <player number="1" ><name>Yoshikatsu Kawaguchi</name></player>
  <player number="3" ><name>Naoki Matsuda</name></player>
  <player number="4" ><name>Ryuzo Morioka</name></player>
  <player number="16"><name>Koji Nakata</name></player>
  <player number="21"><name>Yasuhiro Hato</name></player>
  <player number="14"><name>Teruyoshi Ito</name></player>
  <player number="17"><name>Kazuyuki Toda</name></player>
  <player number="6" ><name>Toshihiro Hattori</name></player>
  <player number="8" ><name>Hiroaki Morishima</name></player>
  <player number="9" ><name>Atsushi Yanagisawa</name></player>
  <player number="22"><name>Takayuki Suzuki</name></player>
</team>

 ここには team エレメントの中に player エレメントがあり、player エレメントは number アトリビュートと name エレメントを持っています。この構造を記述するRELAX NG文法は次のようになります。 This XML instance has a team element as the root element, and the team element has one or more player elements. Additionally, the each player element has a number attribute and name element. A RELAX NG grammar representing this structure is following.

<?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という名前でアクセスできるようにしています。 Additional information peculiar to RelaxNGCC, which has the namespace prefix "c" is emphasized with red. At first, look the data element[1] that indicates the value of number attribute. It has an alias attribute. The alias attribute declares that the Java source code in java element can refer to the value of data element using the variable "number". In the same way, the value of name element[3] is associated with the variable "name".

 次に、"java"エレメント([2],[4])です。これは、XML文書を読んだときに実行するJavaコード断片を記述したものです。ここでは文書の中身を確認するためにSystem.outに出力しています。 Next, we introduce the "java" elements ([2],[4]). We can use a java element with a chip of Java source code to describe an action invoked by reading a fragment of XML instance. In the example above, the generated code prints the contents of number attribute and name element to System.out.

 さらに、これら全体はoneOrMore内に入っているので、コードはplayerエレメントの個数だけ繰り返し実行されることになります。 Be careful that the System.out.println is executed the same number of times as the number of player elements since all the java elements are enclosed by the oneOrMore element.

 では、これをRelaxNGCCにかけてみます。 Now, let's compile this grammar using RelaxNGCC.

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

そうすると、カレントディレクトリにJavaのソースファイルが出力されます。これの一部は次のようになっています。完全なものはここにあります。 As a result, RelaxNGCC generates a Java source file at current directory. A part of it is following, and complete source is available from here.

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;
(中略)(omitted some lines)
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();

}
(中略)(omitted some lines)
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;

}
}
}
}
これをコンパイルして実行すると、 If you compile the file and run it, you will see the result as following.
$ 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
鈴木隆行
1
Yoshikatsu Kawaguchi
3
Naoki Matsuda
4
Ryuzo Morioka
16
Koji Nakata
21
Yasuhiro Hato
14
Teruyoshi Ito
17
Kazuyuki Toda
6
Toshihiro Hattori
8
Hiroaki Morishima
9
Atsushi Yanagisawa
22
Takayuki Suzuki

となります。

 このように最も基本的なRelaxNGCCの使い方は、dataまたはtextエレメントにaliasアトリビュートを使って名前を付け、javaエレメントでコードを埋め込むことです。javaエレメント内からはJavaでできるあらゆることが可能なので、外部のライブラリを呼んだりデータベースにアクセスしたりといったことも簡単です。 Thus, the most basic way of using RelaxNGCC is naming a data or a text element with an alias attribute, and embedding the action you want with a java element. Since you can write any Java code in the java elements, it is easy to perform flexible actions such as calling external libraries or accessing databases.


RelaxNGCC home