If you ever needed to validate a CALS table using schematron

June 3, 2011

Here is a nifty little schematron rule to validate CALS tables.  In Particular it checks to make sure
that morerows, namest, nameend parameters are properly placed.  I hope this helps someone, it took me some time to hack it together.

<sch:rule id="TABLE_ROWS" context="*:row" xmlns:sch="http://purl.oclc.org/dsdl/schematron"><sch:let name="entry-count" value="count(*:entry)"/><sch:let name="tgroup" value="./ancestor::*:tgroup[1]"/><sch:let name="cols-count" value="xs:integer($tgroup/@cols)"/><sch:let name="colspans" value=" sum( for $e in ./*:entry[@namest] return xs:integer(replace($e/@nameend,'[^\d]','')) - xs:integer(replace($e/@namest,'[^\d]','')))"/><sch:let name="morerows" value="(preceding-sibling::row[*:entry/@morerows])[position() eq last()]"/><sch:let name="morerows-value" value="$morerows/*:entry/@morerows[position() eq 1]"/><sch:let name="morerows-position" value="count($morerows/preceding-sibling::*:row)"/><sch:let name="rows-distance" value="count(preceding-sibling::*:row)"/><sch:let name="morerows-distance" value="$rows-distance - $morerows-position"/><sch:let name="morerows-count" value=" if($morerows) then if($morerows-distance le xs:integer($morerows-value)) then count($morerows/*:entry) - 1 else 0 else 0"/><sch:assert id="TABLE_ROW_MATCH_COLS_COUNT" test="$cols-count eq count(*:entry) + $morerows-count + $colspans" flag="ERROR">
The Count of row/*:entry elements must match column specification in tgroup
[DEBUG:
|$morerows distance: <sch:value-of select="$morerows-distance "/>

|$morerows value: <sch:value-of select=”$morerows-value”/>
|in-distance: <sch:value-of select=”$morerows-distance le xs:integer($morerows-value)”/>
|more-rows-entry-count:<sch:value-of select=”count($morerows/*:entry) – 1″/>]
</sch:assert></sch:rule>

The Count of row/*:entry elements must match column specification in tgroup
[DEBUG:
|$morerows distance:
|$morerows value:
|in-distance:
|more-rows-entry-count:]