# 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