RelaxNGCC Tutorial 1

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.

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="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>

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>

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".

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.

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.

Now, let's compile this grammar using RelaxNGCC.

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

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
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

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