an implementation of xsl:key for XT (2nd attempt)

Subject: an implementation of xsl:key for XT (2nd attempt)
From: Denys Duchier <Denys.Duchier@xxxxxxxxxxxx>
Date: 18 Aug 1999 23:27:08 +0200
Hi James,

I sent a message earlier, but I don't think it made it through.  In
the process of trying to clarify my understanding of xsl:key, I
prototyped an implementation of it in XT.  The idea is quite simple
and is described in more detail below.  In a nutshell, the mechanism
that creates key entries is explained and implemented by reduction to
template processing.  I wrote this in the past couple of days and I
have only minimally tested it (I tested a bit further this evening and
removed a couple of obvious bugs).  This being my first real
programming project in Java, I don't think the result should be
trusted blindly, but it appears to perform as expected.

I made a gzipped tar archive of my contribution available at

               http://www.ps.uni-sb.de/~duchier/XT.tgz

Here is the README file that explains the technique is some detail:

======================================================================
		    PROCESSING OF KEY DECLARATIONS
======================================================================

The idea is to compile key declarations into templates.  Thus the
processing of xsl:key can be explained and implemented in terms of a
matching process that we already have and understand.

When there are xsl:key declarations, processing starts in mode
xkey:top instead of the default null.

Suppose the document contains the following xsl:key declarations:

	<xsl:key name=NAME1 match=MATCH1 use=USE1/>
	...
	<xsl:key name=NAMEn match=MATCHn use=USEn/>

Then the templates below are created.  First a new `top level'
template: its job is to first create all key entries and then simply
revert to normal processing.

The key entries are created by a recursive process that starts from a
root set of nodes specified by an expression ROOTSET.  In the current
draft, ROOTSET is simply "/".

<template match="/" mode="xkey:top">
  <for-each select=ROOTSET>
    <apply-templates mode="xkey:decl.1" select="."/>
    ...
    <apply-templates mode="xkey:decl.n" select="."/>
    <apply-templates mode="xkey:rec" select="*"/>
  </for-each>
  <apply-templates select="."/>
</template>

Then there is a template that performs the recursive step of the
indexing process.

<template match="node()" mode="xkey:rec">
  <apply-templates mode="xkey:decl.1"/>
  ...
  <apply-templates mode="xkey:decl.n"/>
  <apply-templates mode="xkey:rec""/>
</template>

Finally there is a new mode and a single template for every xsl:key
declaration.  For e.g. xsl:key declaration number 3, we have:

<template match=MATCH3 mode="xkey:decl.3">
  <if test="xkey:use(NAME3,USE3,.)"/>
</template>
<!-- no recursion -->
<template match="/|node()" mode="xkey:decl.3" priority="-2.0"/>

The default rule _blocks_ recursion.  The recursive step is performed
only once in the template shown earlier.  The xsl:if instruction is
used purely for the side effect of invoking the xkey:use() function.
The job of this function is to evaluate USE3 in the context of the
match and register all corresponding key entries.

======================================================================
			       PROPOSAL
======================================================================

The fact that the root set expression is "/" considerably limits the
usefulness of the xsl:key mechanism.  I propose to allow:

	<xsl:apply-keys select=ROOTSET/>

to permit an arbitrary expression.  Thus you could have:

	<xsl:apply-key select="/|document('foo.xml')"/>


-- 
Dr. Denys Duchier			Denys.Duchier@xxxxxxxxxxxx
Forschungsbereich Programmiersysteme	(Programming Systems Lab)
Universitaet des Saarlandes, Geb. 45	http://www.ps.uni-sb.de/~duchier
Postfach 15 11 50			Phone: +49 681 302 5618
66041 Saarbruecken, Germany		Fax:   +49 681 302 5615


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread