<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet href="/style/browser.xsl" type="text/xsl"?>
<essay xmlns="http://docbook.org/ns/docbook"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
       xmlns:dc='http://purl.org/dc/elements/1.1/'
       xmlns:dcterms="http://purl.org/dc/terms/"
       xmlns:gal='http://norman.walsh.name/rdf/gallery#'
       version='pto'>
<info>
<title>Validating XSLT 2.0</title>
<volumenum>7</volumenum>
<issuenum>132</issuenum>
<pubdate>2004-07-25T09:32:35-04:00</pubdate>
<date>$Date: 2005-09-11 10:27:02 -0400 (Sun, 11 Sep 2005) $</date>
<author><personname>
<firstname>Norman</firstname><surname>Walsh</surname>
</personname></author>
<copyright><year>2004</year><holder>Norman Walsh</holder></copyright>
<abstract>
<para>A RELAX NG Grammar for XSLT 2.0 and the marvelous simplicity
of externalRef.</para>
</abstract>
</info>

<para xml:id='p1'>As XSLT 2.0 matures, and with
<personname><firstname>Michael</firstname>
<surname>Kay</surname></personname>’s excellent processor (from
<phrase xlink:href="http://www.saxonica.com/">Saxonica</phrase>) available to start
putting it through it’s paces in practice, I’ve been writing more and
more XSLT 2.0 stylesheets.</para>

<para xml:id='p2'>I’ve been doing it in <application>emacs</application>, of course,
with <systemitem role="emacs-mode">nxml</systemitem> mode. That ships with
an XSLT 1.0 grammar and I’ve just
been ignoring the apparent “errors” in 2.0 stylesheets.</para>

<para xml:id='p3'>Until yesterday, that is. Yesterday, I got fed up with my editor’s
failure to detect <tag class="attribute">as</tag> attributes in the wrong place
and I went ahead and constructed an
<phrase xlink:href="examples/xslt20.rnc">XSLT 2.0 grammar</phrase>.</para>

<para xml:id='p4'><personname><firstname>James</firstname>
<surname role="suppress">Clark</surname></personname> got his grammar for 1.0
by running some XSLT over the grammar description in the spec. Not having
that stylesheet handy, I just did it by hand. If you find any errors, let me know
and I’ll fix them.</para>

<para xml:id='p5'>Having a grammar for 2.0 is nice (a usable grammar, I mean, the W3C XML
Schema version in the spec doesn’t do me any good), but it raises a new problem:
how do I get emacs to use the 2.0 grammar for 2.0 stylesheets and the 1.0 grammar
for 1.0 stylesheets?</para>

<para xml:id='p6'>The short answer is: there isn’t any way (it could be done, but not with
any of the techniques provided by an unmodified
<systemitem role="emacs-mode">nxml</systemitem> mode). What I really needed was
a stylesheet for <emphasis>either</emphasis> version of XSLT.</para>

<para xml:id='p7'>As I pondered how this might be done, how I might reconstruct the various
patterns to account for whether or not they were descended from a
<tag>xsl:stylesheet</tag> element with a <tag class="attribute">version</tag>
attribute of “1.0” or “2.0”, I remembered “<code>externalRef</code>”, a RELAX NG
feature I hadn’t really needed before.</para>

<para xml:id='p8'>You want to see how easy it is to build a RELAX NG grammar that will
validate either XSLT 1.0 or XSLT 2.0 stylesheets? It’s just this simple:</para>

<programlisting>xslt10 = external "xslt10.rnc"
xslt20 = external "xslt20.rnc"
start = xslt10 | xslt20</programlisting>

<para xml:id='p9'>How sweet is that? For your convenience, I’ve put
<phrase xlink:href="examples/xslt.rnc">that schema</phrase> and a
<phrase xlink:href="examples/xslt10.rnc">copy of James’ original</phrase> online
too.</para>

<para xml:id='p10'>I should point out that this doesn’t automatically handle mixtures of
XSLT 1.0 and XSLT 2.0 elements in the same stylesheet. But it does validate
entire stylesheets one way or the other.</para>

</essay>
