RE: [xsl] glossary sorting/indexing question

Subject: RE: [xsl] glossary sorting/indexing question
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 20 May 2008 14:52:56 +0100
> The xsl file says version 2.0. I believe it is only using 1.0 
> features, and it runs in Saxon if I declare it as version 
> 1.0, but it only runs in XMLSpy if it is given version 2.0. 
> XMLSpy complains about the key definition, but that's not a 
> big concern.

An XSLT 2.0 processor that supports backwards compatibility mode (like
Saxon) will allow some or all of the modules to say version="1.0", and will
run the code in those modules in backwards compatibility mode (which as
David says only makes a difference if you are relying on features that you
would be unwise to exploit). Specifying version="1.0" does NOT disable use
of 2.0 features if you are running a 2.0 processor.

This is also true for AltovaXML, the engine inside XMLSpy. However, by
default XMLSpy will invoke an XSLT 1.0 engine if the principal stylesheet
module specifies version="1.0", and an XSLT 2.0 engine if it specifies XSLT
2.0. Therefore, in this mode of operation, 2.0 constructs will be disallowed
if the principal module specifies version="2.0". Note that if you're using
XMLSpy it's important to use the 2008 edition - support for XSLT 2.0 in
earlier versions is very buggy.

>Can I <xsl:import> existing version 1.0 stylesheets which do other useful
things into a 2.0 stylesheet which does the glossary-specific stuff? Or do I
have to change them all? 

No, you don't have to change them.

Michael Kay
http://www.saxonica.com/

> 
> I'm not that au fait with XSL version 2.0 but I suspect that 
> it is probably a lot neater for this kind of job. Even in 1.0 
> I'm sure there is a better way of coding the stylesheet which follows.
> 
> XML document (shortgloss.xml):
> ------
> <?xml version="1.0" encoding="UTF-8"?>
> <document>
>  <title>Glossary</title>
>  <section>
>   <title>Benefit</title>
>   <para>blah blah.</para>
>  </section>
>  <section>
>   <title>Access mode</title>
>   <para>blah blah.</para>
>  </section>
>  <section>
>   <title>ACRONYM</title>
>   <para>blah blah.</para>
>  </section>
>  <section>
>   <title>Alice</title>
>   <para>blah blah.</para>
>  </section>
>  <section>
>   <title>bridging</title>
>   <para>blah blah.</para>
>  </section>
>  <section>
>   <title>Access</title>
>   <para>blah blah.</para>
>  </section>
> </document>
> 
> Stylesheet (shortgloss.xsl):
> ------
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE xsl:stylesheet [<!ENTITY nbsp "&#160;">]> 
> <xsl:stylesheet version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
> exclude-result-prefixes="xs"> <xsl:output method="html" 
> encoding="us-ascii" indent="no"
> doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
> doctype-system="http://www.w3.org/TR/html4/loose.dtd"; />
> 
> <!-- constants -->
> <xsl:variable name="upchars" 
> select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" /> <xsl:variable 
> name="lochars" select="'abcdefghijklmnopqrstuvwxyz'" />
> 
> <!-- subhead key -->
> <xsl:key name="subhead" match="/document/section"
> use="translate(substring(./title,1,1),$lochars,$upchars)" />
> 
> <xsl:template match="/document">
> <html>
> <head><title><xsl:apply-templates select="title" 
> /></title></head> <body>
>   <h1><xsl:apply-templates select="title" /></h1>
>   <xsl:for-each select="/document/section[count(. |
> key('subhead',translate(substring(./title,1,1),$lochars,$upcha
> rs))[1]) = 1]">
> 	<xsl:sort select="translate(./title,$lochars,$upchars)" />
> 	<xsl:variable name="initial"
> select="translate(substring(./title,1,1),$lochars,$upchars)" />
> 	<a name="{$initial}" />
> 	<h2><xsl:value-of select="$initial" /></h2>
> 	<h4>
> 	  <xsl:for-each select="key('subhead',$initial)">
> 		<xsl:sort 
> select="translate(./title,$lochars,$upchars)" />
> 		<xsl:if test="position()=1">
> 		  <xsl:value-of select="./title" />
> 		</xsl:if>
> 	  </xsl:for-each>
> 	  <xsl:text> - </xsl:text>
> 	  <xsl:for-each select="key('subhead',$initial)">
> 		<xsl:sort 
> select="translate(./title,$lochars,$upchars)" />
> 		<xsl:if test="position()=last()">
> 		  <xsl:value-of select="./title" />
> 		</xsl:if>
> 	  </xsl:for-each>
> 	</h4>
> 	<xsl:for-each select="key('subhead',$initial)">
> 	  <xsl:sort select="translate(./title,$lochars,$upchars)" />
> 	  <p><xsl:apply-templates select="."/></p>
> 	</xsl:for-each>
>   </xsl:for-each>
> </body>
> </html>
> </xsl:template>
> 
> <xsl:template match="section">
>   <xsl:apply-templates select="title" /> </xsl:template>
> 
> <xsl:template match="title">
>   <xsl:value-of select="." />
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> Thanks for any advice
> Trevor

Current Thread