I have now modified the nice XSLT stylesheet of David Carlisle in
order to get XPath testing that can be easily transferred from XSLT to
Schematron.
Basically I have made templates for h1-h4 (templates for h5 and h6 are
not necessary, they can be directly followed by any heading except h1)
to get rid of xsl:for-each, and I have provided for more exact error
messages.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="xhtml">
<xsl:output indent="yes"/>
<xsl:variable name="h"
select="//xhtml:*[matches(local-name(),'^h[1-6]')]/number(substring(local-name(),2))"/>
<xsl:template match="/">
<test>
<xsl:if test="not($h[1]=1)"><error>h1 must be the first
heading.</error></xsl:if>
<xsl:if test="not(count($h[.=1])=1)"><error>There can only
be one h1.</error></xsl:if>
<xsl:apply-templates
select="//xhtml:h1|//xhtml:h2|//xhtml:h3|//xhtml:h4"/>
</test>
</xsl:template>
<xsl:template match="//xhtml:h1">
<xsl:variable name="b"
select="count(preceding::xhtml:*[matches(local-name(),'^h[1-6]')])
+ 1"/>
<xsl:if test="$h[$b + 1]-$h[$b] gt 1">
<error>The first heading after h1 can not be
h<xsl:value-of select="$h[$b + 1]"/>. Only h2 is allowed.</error>
</xsl:if>
</xsl:template>
<xsl:template match="//xhtml:h2">
<xsl:variable name="b"
select="count(preceding::xhtml:*[matches(local-name(),'^h[1-6]')])
+ 1"/>
<xsl:if test="$h[$b + 1]-$h[$b] gt 1">
<error>The first heading after h2(<xsl:value-of
select="count(preceding::xhtml:h2) + 1" />) can not be h<xsl:value-of
select="$h[$b + 1]"/>. Only h2 or h3 is allowed.</error>
</xsl:if>
</xsl:template>
<xsl:template match="//xhtml:h3">
<xsl:variable name="b"
select="count(preceding::xhtml:*[matches(local-name(),'^h[1-6]')])
+ 1"/>
<xsl:if test="$h[$b + 1]-$h[$b] gt 1">
<error>The first heading after h3(<xsl:value-of
select="count(preceding::xhtml:h3) + 1" />) can not be h<xsl:value-of
select="$h[$b + 1]"/>. Only h2 or h3 or h4 is allowed.</error>
</xsl:if>
</xsl:template>
<xsl:template match="//xhtml:h4">
<xsl:variable name="b"
select="count(preceding::xhtml:*[matches(local-name(),'^h[1-6]')])
+ 1"/>
<xsl:if test="$h[$b + 1]-$h[$b] gt 1">
<error>The first heading after h4(<xsl:value-of
select="count(preceding::xhtml:h4) + 1" />) can not be h6. Only h2 or
h3 or h4 or h5 is allowed.</error>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Cheers,
Jesper Tverskov
http://www.xmlplease.com/schematron
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--