Subject: [xsl] Testing implicit XHTML hierarchy From: "Jesper Tverskov" <jesper@xxxxxxxxxxx> Date: Wed, 4 Jul 2007 21:30:19 +0200 |
I want to make XPath expressions later to be transferred from XSLT to Schematron that can validate an implicit XHTML hierarchical structure that is the correct use of heading elements h1-h6 .
1. There can only be one h1, and it must be the first heading. 2. The first heading after h1 must be h2. 3. The first heading after h2 must be h2 or h3. 4. The first heading after h3 must be h2 or h3 or h4. 5. The first heading after h4 must be h2 or h3 or h4 or h5 6. The first heading after h5 or h6 can be anything except h1.
My expressions in the following XSLT stylesheet work fine. I think. No problem. But I am wondering if there are easier ways to make the expressions or if I have forgotten something.
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xhtml"> <xsl:output indent="yes"/> <xsl:template match="/"> <test> <xsl:apply-templates select="xhtml:html/xhtml:body//xhtml:h1 | xhtml:html/xhtml:body//xhtml:h2 | xhtml:html/xhtml:body//xhtml:h3 | xhtml:html/xhtml:body//xhtml:h4" /> </test> </xsl:template>
<xsl:template match="xhtml:html/xhtml:body//xhtml:h1"> <xsl:if test="preceding::xhtml:h1"> <error>There can only be one h1</error> </xsl:if> <xsl:if test="preceding::xhtml:h2 or preceding::xhtml:h3 or preceding::xhtml:h4 or preceding::xhtml:h5 or preceding::xhtml:h6"> <error>h1 must be the first heading.</error> </xsl:if> <xsl:if test="following::xhtml:h2 or following::xhtml:h3 or following::xhtml:h4 or following::xhtml:h5 or following::xhtml:h6"> <xsl:if
test="not(following::xhtml:h2[1][not(preceding::xhtml:h3)][not(preceding::xhtml:h4)][not(preceding::xhtml:h5)][not(preceding::xhtml:h6)])"> <error>The first heading after h1 must be h2</error> </xsl:if> </xsl:if> </xsl:template>
<xsl:template match="xhtml:html/xhtml:body//xhtml:h2"> <xsl:if test="following::xhtml:h4[1][preceding::xhtml:h2[1] eq current()]"> <xsl:if
test="following::xhtml:h4[1][not(preceding::xhtml:h2[1][preceding::xhtml:h2[1] eq current()])] and following::xhtml:h4[1][not(preceding::xhtml:h3[1][preceding::xhtml:h2[1] eq current()])]"> <error>The first heading after h2 must be h2 or h3</error> </xsl:if> </xsl:if> <xsl:if test="following::xhtml:h5[1][preceding::xhtml:h2[1] eq current()]"> <xsl:if
test="following::xhtml:h5[1][not(preceding::xhtml:h2[1][preceding::xhtml:h2[1] eq current()])] and following::xhtml:h5[1][not(preceding::xhtml:h3[1][preceding::xhtml:h2[1] eq current()])]"> <error>The first heading after h2 must be h2 or h3</error> </xsl:if> </xsl:if> <xsl:if test="following::xhtml:h6[1][preceding::xhtml:h2[1] eq current()]"> <xsl:if
test="following::xhtml:h6[1][not(preceding::xhtml:h2[1][preceding::xhtml:h2[1] eq current()])] and following::xhtml:h6[1][not(preceding::xhtml:h3[1][preceding::xhtml:h2[1] eq current()])]"> <error>The first heading after h2 must be h2 or h3</error> </xsl:if> </xsl:if> </xsl:template>
<xsl:template match="xhtml:html/xhtml:body//xhtml:h3"> <xsl:if test="following::xhtml:h5[1][preceding::xhtml:h3[1] eq current()]"> <xsl:if
test="following::xhtml:h5[1][not(preceding::xhtml:h3[1][preceding::xhtml:h3[1] eq current()])] and following::xhtml:h5[1][not(preceding::xhtml:h4[1][preceding::xhtml:h3[1] eq current()])] and following::xhtml:h5[1][not(preceding::xhtml:h2[1][preceding::xhtml:h3[1] eq current()])] "> <error>The first heading after h3 must be h2 or h3 or h4</error> </xsl:if> </xsl:if> <xsl:if test="following::xhtml:h6[1][preceding::xhtml:h3[1] eq current()]"> <xsl:if
test="following::xhtml:h6[1][not(preceding::xhtml:h3[1][preceding::xhtml:h3[1] eq current()])] and following::xhtml:h6[1][not(preceding::xhtml:h4[1][preceding::xhtml:h3[1] eq current()])] and following::xhtml:h5[1][not(preceding::xhtml:h2[1][preceding::xhtml:h3[1] eq current()])] "> <error>The first heading after h3 must be h2 or h3 or h4</error> </xsl:if> </xsl:if>
<xsl:template match="xhtml:html/xhtml:body//xhtml:h4"> <xsl:if test="following::xhtml:h6[1][preceding::xhtml:h4[1] eq current()]"> <xsl:if
test="following::xhtml:h6[1][not(preceding::xhtml:h4[1][preceding::xhtml:h4[1] eq current()])] and following::xhtml:h6[1][not(preceding::xhtml:h5[1][preceding::xhtml:h4[1] eq current()])] and following::xhtml:h6[1][not(preceding::xhtml:h2[1][preceding::xhtml:h4[1] eq current()])] and following::xhtml:h6[1][not(preceding::xhtml:h3[1][preceding::xhtml:h4[1] eq current()])] "> <error>The first heading after h4 must be h2 or h3 or h4 or h5</error> </xsl:if> </xsl:if> </xsl:template>
Cheers, Jesper Tverskov
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Removing an XML Attribute, Michael Kay | Thread | Re: [xsl] Testing implicit XHTML hi, bryan rasmussen |
[xsl] Re: accessing a node-set in v, Sam Carleton | Date | Re: [xsl] Testing implicit XHTML hi, bryan rasmussen |
Month |