Skip to: Site menu | Main content

Groovy 

      Download | Documentation | Developers | Community

An agile dynamic language for the Java Platform

Validating XML with RELAX NG Add comment to Wiki View in Wiki Edit Wiki page Printable Version

This example assumes the following class is already on your CLASSPATH:

XmlExamples.groovy
class XmlExamples {
  static def CAR_RECORDS = '''
    <records>
      <car name='HSV Maloo' make='Holden' year='2006'>
        <country>Australia</country>
        <record type='speed'>Production Pickup Truck with speed of 271kph</record>
      </car>
      <car name='P50' make='Peel' year='1962'>
        <country>Isle of Man</country>
        <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
      </car>
      <car name='Royale' make='Bugatti' year='1931'>
        <country>France</country>
        <record type='price'>Most Valuable Car at $15 million</record>
      </car>
    </records>
  '''
}

A number of RELAX NG validators are available (e.g. MSV and Jing). Rather than using the APIs for these validators directly, you might want to consider using the ISO RELAX project's common JARV API for accessing validators. Using this common API, you can switch between the available validators without changing your source code.

An even better option (if you are using Java 5 or above, or otherwise have JAXP 1.3 available to you) is to use the ISORELAX JARV to JAXP 1.3 Xml Validation Engine Adaptor. This hooks into the built-in JAXP validation Factory support in JAXP and makes the code that you use to access the RELAX NG validator the same as you would do for a W3C XML Schema validator.

Here is what the code would look like:

// require(url:'http://iso-relax.sourceforge.net/', jar:'isorelax.jar')
// require(groupId:'org.iso_relax.verifier.jaxp.validation', artifactId:'isorelax-jaxp-bridge', version:'1.0')
// require(url:'https://msv.dev.java.net/', jar:'msv.jar')

def rng = '''
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <ref name="records"/>
    </start>
    <define name="car">
        <element name="car">
            <attribute name="make">
                <data type="token"/>
            </attribute>
            <attribute name="name">
                <text/>
            </attribute>
            <attribute name="year">
                <data type="integer"/>
            </attribute>
            <ref name="country"/>
            <ref name="record"/>
        </element>
    </define>
    <define name="country">
        <element name="country">
            <text/>
        </element>
    </define>
    <define name="record">
        <element name="record">
            <attribute name="type">
                <data type="token"/>
            </attribute>
            <text/>
        </element>
    </define>
    <define name="records">
        <element name="records">
            <oneOrMore>
                <ref name="car"/>
            </oneOrMore>
        </element>
    </define>
</grammar>
'''.trim()

import javax.xml.XMLConstants
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory

def factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI)
def schema = factory.newSchema(new StreamSource(new StringReader(rng)))
def validator = schema.newValidator()
validator.validate(new StreamSource(new StringReader(XmlExamples.CAR_RECORDS)))