Showing posts with label Validation. Show all posts
Showing posts with label Validation. Show all posts

Thursday, January 7, 2010

Schematron: Using the Number() Function Versus Casting

There are situations where it becomes necessary to test the value of a numeric element to ensure it meets some minimum or maximum value.  As Schematron is capable of treating any element as a string, it is generally a best practice to cast the value to a numeric data type first. 

For example, on a citation or a complaint document it may be necessary to check the fine or bail amount to ensure it is greater than zero.  This could be done with the following Schematron assert statement:

<assert test="xsd:double(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be less than zero.
</assert>

While the above would work when a value is provided in the nc:ObligationDueAmount element, an XSLT error would be raised in the following circumstances:

  • Value is blank or null
      • <nc:ObligationDueAmount></nc:ObligationDueAmount>
  • Value is omitted
      • <nc:ObligationDueAmount/>
  • Value is a string value
      • <nc:ObligationDueAmount>N/A</nc:ObligationDueAmount>

For this reason, it is often preferable to use the native XPath function number().  As described by Ms. Priscilla Walmsley in her O’Reilly book XQuery, this function will prevent the XSLT parser from throwing an error and instead return the value ‘NaN’ (Not a Number).  The following would be the same way the Schematron test could be written using the number() function instead:

<assert test="number(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be less than zero.
</assert>
<assert test="nc:ObligationDueAmount and string-length(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be left blank or otherwise omitted.
</assert>

While a few more lines are required, this prevents a runtime parser error from being raised and causing havoc with the validation engine.

Monday, November 23, 2009

Schematron: Nesting XPath Values Within an XPath Predicate

In previous examples, we have seen the usage of a temporary variable or <let> tag to store a value which is later used in an XPath predicate (the square brackets surrounding the index of an element array).  It is important to note that this is not required.  A simple XPath statement can be used in the predicate for any other XPath statement.  For example see the following:

<pattern id="wEmptyMetadataComment">
  <title>Ensure person metadata comment is not blank.</title>
  <rule context="/ns:SomeDocument/nc:Person">
    <assert test="string-length(/ns:SomeDocument/nc:Metadata[@s:id=current()/@s:metadata]/nc:CommentText) &gt; 0">
      Comments regarding a person should not be blank.
    </assert>
  </rule>
</pattern>

In the above example, simply the attribute @s:id=/ns:SomeDocument/nc:Person/@s:metadata is used to identify which specific Metadata element should be examined.  With the context defined as /ns:SomeDocument/nc:Person, the rule will loop through each nc:Person element and use the appropriate @s:metadata value in each subsequent pass.

[Updated: Corrected Syntax on 04-01-2010]

Monday, October 5, 2009

XML Editor Support for Schematron

XML editors are one of the primary tools in a practitioner's toolbox and as such, are the first place many of us look for assistance using a complex validation engine such as Schematron. Currently today editors on the market have different levels of support for Schematron; as it is at the core a multi-pass validation engine. The following table should provide you with links to where tutorials for some of the most common XML editors are located:
EditorNative Schematron Validation?Native Schematron Editing?Tutorial
oXygenYesYeshttp://www.oxygenxml.com/validation.html
XMLSpyNoYeshttp://xml.sys-con.com/node/40656
EditixYesYesNone available
Update: 2009-10-05 - Adding Hyperlink to Editor websites.