Sample Code

Some code samples

Validating properties

PageSeeder properties often have specific constraints associated with them including:

  • a minimum or maximum length
  • a specific datatype
  • matching a regular expression
  • matching a value in a list

Basics

Property rule

Most rules applying to images should match the <property> element based on its name:

<!-- Matches a specific property in PSML based on name -->
<sch:rule context="property[@name = 'acme']">

   <!-- Assertions and reports here ... -->

</sch:rule>

Alternatively, the datatype can be used.

<!-- Matches a specific property in PSML based on datatype -->
<sch:rule context="property[@datatype = 'date']">

   <!-- Assertions and reports here ... -->

</sch:rule>

Message

The message returned by Schematron when reported or when an assertion fail should allow the user to quickly identify the problem so that it can be fixed.

Since constraints are usually associated with a specific property, you can use the attributes @name and/or @title to help the user identify which property was affected.

It is often useful to also include the offending value or values using the @value attribute for single-valued properties or the  <value> element for multi valued properties.

In order to provide additional context, it is often useful to provide the properties fragment or section ID.

Note

Properties fragments often have a unique ID specified by the document template as opposed to default fragments which tend to have auto-generated IDs, so it is often sufficient to simply use the ID of the <properties-fragment> element.

For example:

Property '<sch:value-of select="@name"/>'
in fragment '<sch:value-of select="parent::properties-fragment/@id"/>'

Can be used to display:

Property 'isbn' in properties fragment 'book-metadata'.

Single value vs. multiple values

Some properties only have a single value using a @value attribute while other properties contain zero or multiple values specified in the <value> element. Whether a property is single-valued or multi-valued is determined by the @count attribute.

Validation should expect having to deal with either option but not both.

Value test

One significant difference between single-valued and multi-valued properties:

  • the @value attribute is always present for a single-valued property, so tests should expect that @value will match 1 value.
  • <value> elements are only present for multi-valued properties if a value has been specified, so tests should expect that value will match 0 or more values.

Property count

Properly designed document templates should ensure that for any given property, it will be either always single-valued or multi-valued for every document instance. In other words, proper design should ensure that there will not be any document where a property is defined as a single-valued and other documents where the same property is defined as multi-valued.

In cases when a document template has changed and documents and may be inconsistent, the tests below can be used based on the @value  and @count attributes.

Using the <value> element is not reliable, because it is not necessarily specified.

Single-valued

<sch:rule context="property[@name='abc']">

  <!-- Expecting a single-valued property -->
  <sch:assert test="@value and (@count=1 or not(@count))">Property 
    '<sch:value-of select="@name"/>' should be single-valued.</sch:assert>

</sch:rule>

Multi-valued

<sch:rule context="property[@name='xyz']">

  <!-- Expecting a multi-valued property -->
  <sch:assert test="not(@value) and count and @count != '1'">Property
   '<sch:value-of select="@name"/>' should be multi-valued.</sch:assert>

</sch:rule>

Validating XML schema datatypes

A common constraint is to check that a property matches a specific XML Schema datatype .

Note

To use the XML schema datatypes, make sure the XML Schema namespace is both declared (using xmlns) and mapped (using <sch:ns />)

<sch:ns prefix="xs" uri="http://www.w3.org/2001/XMLSchema"/>

Limitations

PageSeeder does not use a schema-aware Schematron validator, and therefore the techniques below are limited to the built-in XML Schema datatypes.

Validating dates

To validate that a property value matches a date, it is sufficient to check that it can be casted as an xs:date XML Schema value.

<sch:rule context="property[@datatype='date']">

  <!-- Expecting a date -->
  <sch:assert test="@value castable as xs:date">The value of property
    '<sch:value-of select="@name"/>' should be a date as 'yyyy-mm-dd'
    but was '<sch:value-of select="@value"/>'.</sch:assert>

</sch:rule>

Validating integers

To validate that a property has an integer value, it is sufficient to check that it can be casted as an xs:integer XML Schema value.

<sch:rule context="property[@datatype='integer']">

  <!-- Expecting an integer -->
  <sch:assert test="@value castable as xs:integer">The value of property
   '<sch:value-of select="@name"/>' should be an integer
    but was '<sch:value-of select="@value"/>'.</sch:assert>

</sch:rule>

Validating against a pattern

Using regular expressions is a common way to check that value meets requirements against a specific pattern.

Pattern test

To test that a value matches a regular expression pattern, use the XPath 2.0 matches()  function.

<sch:rule context="property[@name='abc']">

  <sch:assert test="matches(@value, 'REGEX')">The value of property
    '<sch:value-of select="@name"/>' should match pattern
    but was '<sch:value-of select="@value"/>'.</sch:assert>

</sch:rule>

Created on , last edited on