RE: [xsl] 'Variable' question from Newbie

Subject: RE: [xsl] 'Variable' question from Newbie
From: "Passin, Tom" <tpassin@xxxxxxxxxxxx>
Date: Fri, 8 Nov 2002 17:32:12 -0500
[ Surla, Stacy]

J.Pietschmann posted you an answer that referred to grouping.  I thought
I would cast that into a form more like the one you expressed, in case
it would be helpful.

Most of the time, in xslt, you are selecting groups of elements, called
node-sets, and then doing something with them.  The magic lies in
selecting the right set of nodes - that is one of the places where you
learn to think differently.

For grouping, which is your problem, the node-set to be selected is one
containing elements having some unique value.  In your case, that is the
value of the child Discipline elements.  Here is a sketch of the most
common approach in xslt -

Find all the unique grouping titles (or headings, or elements, or
whatever).
For each unique group:
	output its group label (or containing element)
	get all the records for that group
	for each record:
		process the record

Now in xslt, you often do not write the iterations explicitly, because
apply-templates handles all the nodes in the node-set it is given.
Also, there is no guarantee that the processor will really handle them
all in some particular order, although it will finally assemble the
results in the right order.  If you do not specify otherwise, that will
be document order.

The tricky part is generally figuring out how to find out what are the
unique groups, and then selecting node-sets for each one of them.
J.Pietschmann's example combines finding the uniques and transforming
them.  I tend to to separate them for clarity, but that is usually a
matter of style.

His expression

select="Record[
         generate-id()=generate-id(key('r-d',Disciples)]

is a sort of standard way to get the unique elements in xslt 1.0.  key()
returns a node-set that contains all Record elements that match the
Discipline value handed to the key, and generate-id() returns a unique
string for the **first** node in that node-set (that is a piece of
xslt-specific knowledge).  The test returns true only if the node being
checked in fact matches the first one in that node set, because only
then will their generated id values agree.  The expression Record[]
checks the expression for all Record elements.

The net result is that the node-set ends up containing only those nodes
that are the first of a list of all Records with the same Discipline
calue.  This is the set of the nodes having unique values for their
Discipline.

So there is a mixture of general thinking - how do I choose what
elements to process? - and specific xslt technical knowledge - like
generate-id returning a distinct string for the first node in a
node-set.

Cheers,

Tom P

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


Current Thread