RELAX NG by Eric van der Vlist will be published by O'Reilly & Associates (ISBN: 0596004214)

You are welcome to use our annotation system to give your feedback.


Common Patterns

After this overview of the syntax used by pattern facets, let's see some common pattern facets that you may have to use (or adapt) in your schemas or just consider as examples.

Regular expressions treat information in its textual form. This makes them an excellent mechanism for constraining strings.

While numeric types aren't strictly text, pattern facets can still be used to constrain their lexical form and effectively their content.

Dates and time have complex lexical representations. Patterns can give developers extra control over how they are used.

The time zone support of W3C XML Schema is quite controversial and needs some additional constraints to avoid comparison problems. These pattern facets can be kept relatively simple since the syntax of the datetime is already checked by the schema validator and only simple additional checks need to be added. Applications which require that their datetimes specify a time zone may use the following template which checks that the time part ends with a "Z" or contains a sign:

  <define name="dateTimeWithTimezone">
    <data type="dateTime">
      <param name="pattern">.+T[^Z+-]+</param>
    </data>
  </define>

or:

 dateTimeWithTimezone= xsd:dateTime {pattern = ".+T[^Z+-]+"}

Simpler applications that want to make sure that none of their datetime values specify a time zone may simply check that the time part doesn't contain the characters "+", "-", or "Z":

  <define name="dateTimeWithoutTimezone">
    <data type="dateTime">
      <param name="pattern">.+T[^Z+-]+</param>
    </data>
  </define>

or:

 dateTimeWithoutTimezone= xsd:dateTime {pattern = ".+T[^Z+-]+"}

In these two datatypes, we used the separator "T". This is convenient, since no occurrences of the signs can occur after this delimiter except in the time zone definition. This delimiter would be missing if we wanted to constrain dates instead of datetimes, but, in this case, we can detect the time zones on their ":" instead:

  <define name="dateWithTimezone">
    <data type="date">
      <param name="pattern">.+[:Z].*</param>
    </data>
  </define>
  <define name="dateWithoutTimezone">
    <data type="date">
      <param name="pattern">[^:Z]</param>
    </data>
  </define>

or:

dateWithTimezone= xsd:date {pattern = ".+[:Z].*"} 
dateWithoutTimezone= xsd:date {pattern = "[^:Z]"} 

Applications may also simply impose a set of time zones to use:

  <define name="dateTimeInMyTimezones">
    <data type="dateTime">
      <param name="pattern">.+(\+02:00|\+01:00|\+00:00|Z|-04:00)</param>
    </data>
  </define>

or:

 dateTimeInMyTimezones= xsd:dateTime {
 	pattern = ".+(\+02:00|\+01:00|\+00:00|Z|-04:00)"
 }

We can also constrain xsd:duration to a couple of subsets that can be reliably compared. The first datatype will consist of durations expressed only in months and years, and the second will consist of durations expressed only in days, hours, minutes, and seconds. The criteria used for the test can be the presence of a "D" (for day) or a "T" (the time delimiter). If neither of those characters are detected, then the datatype uses only year and month parts. The test for the other type cannot be based on the absence of "Y" and "M", since there is also an "M" in the time part. We can test to ensure that, after an optional sign, the first field is either the day part or the "T" delimiter:

  <define name="YMduration">
    <data type="duration">
      <param name="pattern">[^TD]+</param>
    </data>
  </define>
  <define name="DHMSduration">
    <data type="duration">
      <param name="pattern">-?P((\d+D)|T).*</param>
    </data>
  </define>

or:

YMduration= xsd:duration {pattern = "[^TD]+"} 
DHMSduration= xsd:duration {pattern = "-?P((\d+D)|T).*"} 

It may seem tricky, but this is a powerful tool for resolving complex problems simply.


You are welcome to use our annotation system to give your feedback.
[Annotations for this page]
All text is copyright Eric van der Vlist, Dyomedea. During development, I give permission for non-commercial copying for educational and review purposes. After publication, all text will be released under the Free Software Foundation GFDL.