xsl-list
[Top] [All Lists]

Re: [xsl] Testing implicit XHTML hierarchy

2007-07-04 12:45:36
Well I find this kind of a weird way of doing it, one thing about
having a DSL like Schematron is that you have it because it is easier
to express what you want to do in it rather than in the implementation
language of the DSL. In this case you are expressing it first in the
common implementation language, and then moving it to the domain
specific language.


Cheers,
Bryan Rasmussen


On 7/4/07, Jesper Tverskov <jesper(_at_)tverskov(_dot_)dk> wrote:
hi list

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       .

The rules could be expressed like this:

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>

    <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>

</xsl:stylesheet>

Cheers,
Jesper Tverskov

--~------------------------------------------------------------------
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>
--~--



--~------------------------------------------------------------------
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>
--~--