XML Validation: XML Schema (xsd) vs. Relax NG (rng)

At first, I learned XML Schema but found it hard to deal with unordered xml nodes, plus it’s not that easy to read.

I found out Relax NG, read the tutorial and well, it does the job pretty well!

  • its syntax is self-explanatory
  • it allows to do anything you can do with XML Schema, with greater flexibility (cf. you can load external file, define and extend matching-classes…)
  • it’s far easier to read and memorize
  • you can transparently deal with unordered xml nodes (cf. <interleave> node)

It looks like we can validate xml docs with both XML Schema and Relax-NG using php, at least from version 5.2 (cf. XMLReader class on php documentation) and using DOM from svn snapshot (v5.3)


If you want to validate your xml file agains Relax-NG (or XML Schema or DTD), good news for linux users! You can use xmllint (man xmllint), which is available from libxml2-utils package (“sudo apt-get install libxml2-utils”).

Then run “xmllint –noout –relaxng schema.rng file.xml”.


Below is the XML Schema I started to write:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- <query> "name" attribute pattern
		name is used as uri proxy => of the form: /[module]/[action] 	-->
<xs:simpleType name="xsdQueryName">
<xs:restriction base="xs:string">
<xs:pattern value="/[a-zA-Z]+/[a-zA-Z]([a-zA-Z]|-)+"/>
<!-- <contact> in add-contact query -->
<xs:complexType name="xsdContactToAdd">
<xs:all><!-- this type defaults minOccurs="1" and maxOccurs="1" -->
<xsl:choice><!-- "user_fk" is provided when adding a new contact while "id" is provided when updating an existing contact -->
<xs:element name="id" type="xs:positiveInteger"/>
<xs:element name="user_fk" type="xs:positiveInteger"/>
<xs:element name="email_address" type="xs:normalizedString"/>
<xs:element name="first_name" type="xs:normalizedString" minOccurs="0"/>
<xs:element name="last_name" type="xs:normalizedString" minOccurs="0"/>
<xs:element name="company" type="xs:normalizedString" minOccurs="0"/>
<!-- <contact> node -->
<xs:element name="contact" type="xsdContactToAdd"/>
<!-- <query> node -->
<xs:complexType name="xsdQuery" mixed="true">
<xs:element name="contact"/>
<xs:attribute name="name" type="xsdQueryName" use="required"/>
<xs:element name="query" type="xsdQuery"/>

Not crystal clear, even though I used comments and split validations into sub-units to have a clearer doc


One Trackback

  1. March 4, 2010 : positiveinteger

Post a Comment

Your email is never published nor shared. You're allow to say what you want...

Warning: fsockopen() [function.fsockopen]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/remydamo/websites/qc4blog/www/wp-content/plugins/sweetcaptcha-revolutionary-free-captcha-service/library/sweetcaptcha.php on line 81

Warning: fsockopen() [function.fsockopen]: unable to connect to www.sweetcaptcha.com:80 (php_network_getaddresses: getaddrinfo failed: Name or service not known) in /home/remydamo/websites/qc4blog/www/wp-content/plugins/sweetcaptcha-revolutionary-free-captcha-service/library/sweetcaptcha.php on line 81