# RELAX NG User-Defined Datatype Libraries

Written by Kohsuke KAWAGUCHI

## Introduction

The specification of RELAX NG proclaims that it can work with external datatype libraries. The implication is that you can implement your own datatype library and it should work with existing tools like MSV.

To serve this objective, James Clark and Kohsuke KAWAGUCHI developed a datatype interface for Java, which is hosted at SourceForge.

MSV supports this interface, so you can write your own datatype library on top of this interface and it will work with MSV. One can also expect that a datatype library developed by using this interface will work with many other RELAX NG tools as well.

Custom datatype libraries are very flexible solutions. For example, you can write a datatype that checks the product code by querying a database.

## Sample

For more information about how to develop a datatype library for RELAX NG, please download this (which is developed and maintained by Thai Open Source Software Center.)

## Writing Portable Schema

One problem of using a custom datatype library is the portability; once you use it, your schema will not work with other non-Java RELAX NG tools.

This section explains a technique to avoid this problem. Consider the following schema:

    <grammar datatypeLibrary="urn:custom:datatype:library">
      <start>
        <element name="root">
          <data type="myType"/>
        </element>
      </start>
    </grammar>

As you see, this schema is not portable since some other tools may not recognize "myType" datatype.

You can avoid this problem by writing two schemas. The first schema would be:

    <grammar>
      <start>
        <element name="root">
          <ref name="myType" />
        </element>
      </start>

      <define name="myType">
        <data type="string" />
      </define>
    </grammar>

The point is, to provide a <define> for a datatype. This is much like writing a parameter entity for a datatype in DTD.

Then write a second schema as follows:

    <grammar datatypeLibrary="urn:custom:datatype:library">
      <include name="original.rng">
        <define name="myType">
          <data type="myType" />
        </define>
      </include>
    </grammar>

The first schema is portable since it doesn't use any of the custom datatype libraries. Instead it falls back to the built-in "string" type.

The second schema is relatively short. It just overrides the definition of "myType" by using the custom datatype library. So in environments where the custom datatype library is available, you can use this schema to get a better validation.