Skip to main content

 Sample Code

Some code samples

Validating images

Images in PSML documents often have constraints beyond what the PSML schema requires. This article provides some sample code for common use cases.

Basics

Image rule

Most rules applying to images match the <image> element:

<!-- Matches images in PSML -->
<sch:rule context="image">

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

</sch:rule>

Message

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

On the <image> element, you can use the attributes @src, @uriid and @alt to help the user identify the problematic image. But note, however, that the @alt attribute is not always present.

To know where to fix the problem, it is often useful to provide either the fragment or section ID.

For example:

Image '<sch:value-of select="@alt"/>'
at '<sch:value-of select="@src"/>'
in fragment <sch:value-of select="ancestor::fragment/@id"/>

Can be used to display:

Image 'Program schedule' at '/images/program_sch.png' in fragment 43.

Validating the image reference

From version 5.8, images are no longer simple declarations, but are proper references. So PageSeeder is able to check that images references correspond to actual image files.

Checking that an image is resolved

Similar to unresolved cross-references, unresolved image references are flagged as unresolved using the @unresolved attribute.

Unresolved images might occur after an upload or if an image file is deleted.

The following rule checks that the images are resolved:

<sch:rule context="image">

  <!-- Image has no 'unresolved' attribute -->
  <sch:assert test="not(@unresolved) and @uriid">
     The image at <sch:value-of select="@src"/> is unresolved.
  </sch:assert>

</sch:rule>

The extra check that @uriid exists is for PageSeeder documents from before version 5.8, when @unresolved was introduced. Documents after this point have @unresolved for unresolved images.

Validating dimensions

The following rules define assertions on the @width and @height attributes of the <image> element.

Checking that dimensions are defined

The following rule defines an assertion to check that the @width and @height attributes have been defined on the image element.

<sch:rule context="image">

  <!-- Width is not defined -->
  <sch:assert test="@width">
   The width of this image was not defined:
    <sch:value-of select="@src"/>.
  </sch:assert>

  <!-- Height is not defined -->
  <sch:assert test="@height">
    The height of this image was not defined:
     <sch:value-of select="@src"/>.
  </sch:assert>

</sch:rule>

Checking that dimensions meet criteria

The following rule checks that an image fits within dimensions specified by a minimum and maximum value for width and height.

In this example, we have defined the minimum and maximum dimensions as variables to make it easier to configure.

<sch:rule context="image">

  <!-- Min/max dimensions are defined here -->
  <sch:let name="min-width"  value="400"/>
  <sch:let name="max-width"  value="800"/>
  <sch:let name="min-height" value="200"/>
  <sch:let name="max-height" value="600"/>
 
  <!-- Width exceeds max width -->
  <sch:assert test="@width and @width le $max-width">
     The width of image at '<sch:value-of select="@src"/>' is too large.
     Width is <sch:value-of select="@width"/>
     (max=<sch:value-of select="$max-width"/>px).
  </sch:assert>

  <!-- Width lower than min width -->
  <sch:assert test="@width and @width ge $min-width">
     The width of image at '<sch:value-of select="@src"/>' is too small.
     Width is <sch:value-of select="@width"/>
     (min=<sch:value-of select="$min-width"/>px).
  </sch:assert>

  <!-- Height exceeds max height -->
  <sch:assert test="@height and @height le $max-height">
    The height of image at '<sch:value-of select="@src"/>' is too large.
    Height is <sch:value-of select="@height"/>
    (max=<sch:value-of select="$max-height"/>px).
  </sch:assert>

  <!-- Height lower than min height -->
  <sch:assert test="@height and @height ge $min-height">
    The height of image at '<sch:value-of select="@src"/>' is too small.
     Height is <sch:value-of select="@height"/>
     (min=<sch:value-of select="$min-height"/>px).
  </sch:assert>

</sch:rule>

In the example above, we defined several assertions, but the same requirements could also be validated with less assertions. This would essentially affect the number of errors reported and the error message displayed to the user.

For example, the following rule has the same requirements for the dimensions, but only a single failure is reported with a less precise message. 

<!-- Match images in PageSeeder -->
<sch:rule context="image">

  <!-- Min/max dimensions are defined here -->
  <sch:let name="min-width"  value="400"/>
  <sch:let name="max-width"  value="800"/>
  <sch:let name="min-height" value="200"/>
  <sch:let name="max-height" value="600"/>
 
  <!-- Width exceeds max width -->
  <sch:assert test="@width and @height
                and @width ge $min-width
                and @width le $max-width
                and @height ge $min-height
                and @height le $max-height">
       Image at '<sch:value-of select="@src"/>' 
            does not meet dimensions criteria.
    Dimensions specified were (W×H):
     <sch:value-of select="@width"/>×
     <sch:value-of select="@height"/> 
          but required dimensions are minimum
     <sch:value-of select="$min-width"/>×
     <sch:value-of select="$min-height"/>
                and maximum
     <sch:value-of select="$max-width"/>×
     <sch:value-of select="$max-height"/>.
  </sch:assert>

</sch:rule>

Validating image path

The path to an image is defined in the @src attribute. 

Checking that an image is not archived

The following rule checks that the image is not in the archive folder.

<sch:rule context="image">

  <!-- Image is archived -->
  <sch:assert test="not(contains(@src, '/archive/'))">
    Image at '<sch:value-of select="@src"/>' is archived.
  </sch:assert>

</sch:rule>

Checking that images are in specific folder

From PageSeeder 5.8, the path of resolved images is automatically generated and stored in the @src attribute.

<sch:rule context="image">

  <!-- Define folder here -->
  <sch:let name="folder" value="images"/>

  <!-- Image is archived -->
  <sch:assert test="tokenize(@src,'/')[last()-1] = $folder">
    Image at '<sch:value-of select="@src"/>' is not in folder
    '<sch:value-of select="$folder"/>'.
  </sch:assert>

</sch:rule>
Created on , last edited on