Re: Getting the first and last nodes of a sorted nodeset
2004-04-08 08:10:33
Hi John,
Since XSLT 1.0 works over the source document, and does not have access to
the results of transformation (including sorting), this kind of problem is
just plain hard in the 1.0 version of the language.
There are basically three options that I can think of, each of which have
different strengths and involve different tradeoffs:
1. Sometimes if the sorting logic is not too complex, it is possible to
write it into node selection in more than one place, and/or pass nodes
around as parameters, to achieve the desired result. In your case, this
would mean not calling a template "where the two parameters are the first
and last nodes in a sorted nodeset", but rather where the two parameters
are the nodes that *will be* first and last when the set is sorted. This is
not the cleanest approach, and sometimes it's not even reasonable. But
where it's possible, it keeps to classic 1.0 logic and can be executed by
any XSLT processor in one pass.
2. It's not uncommon when doing serious work to pipeline transformations,
which makes this kind of thing much easier. The sort is performed in the
first pass; the second pass then has access to the sorted order in its
"original" source tree. This approach requires you use one of several ways
to pipeline transformations together, which of course has implications for
your processing architecture (it may be easy or may be hard).
3. Using the XSLT 1.0 extension node-set(), or XSLT 2.0 which includes the
node-set() functionality in its processing model, the two passes can be
executed in a single run of a single stylesheet. Bind the result of your
sort to a variable, turn the variable into a node-set using the node-set()
function (look up "Result Tree Fragment" to learn about the 1.0 restriction
that makes this necessary) -- or, if running 2.0, don't bother since it's
already a node set -- and then process it as if it were input.
Tell us which of these approaches is most reasonable to you and we can look
at it again. (In this case, please provide desired output along with some
accounting of the logic.) Or maybe an intrepid XSLTer has already looked
harder at your code, and can jump in with more specifics. Or maybe you'll
just be able to take this and run with it.
Cheers,
Wendell
At 01:07 PM 4/7/2004, you wrote:
Is it possible in XSLT to call a template one time where the 2
parameters are the first and last nodes in a sorted nodeset? A friend
of mine is trying to get a sorted list of dates and generate output for
all dates from the first to the last (whether they appear in the
original XML or not) via a named template which can take a start date
and a stop date and generate output for all the dates from start to
stop. I can't think of any way to do it.
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root>
<test>
<nd>2003-12-31</nd>
<nd>2004-01-01</nd>
<nd>2004-01-02</nd>
<nd>2004-01-03</nd>
<nd>2004-01-04</nd>
<test>
<nd>2004-01-06</nd>
<nd>2004-01-03</nd>
<nd>2004-03-01</nd>
</test>
</test>
<test>
<nd>2004-02-08</nd>
<nd>2004-01-02</nd>
<nd>2004-02-03</nd>
<nd>2004-01-04</nd>
<nd>2004-02-08</nd>
</test>
</root>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
version='1.0'>
<xsl:output method='html'/>
<xsl:key name='nd_key' match='nd' use='.'/>
<xsl:template match="/root">
<html>
<xsl:for-each
select="//nd[generate-id()=generate-id(key('nd_key',.)[1])]">
<xsl:sort select="."/>
<xsl:value-of select="."/><br/>
<xsl:if test="position()=last()">
<xsl:call-template name="test_template">
<!-- first element ?? What to replace select="." with ?? -->
<xsl:with-param name="b"><xsl:value-of
select="."/></xsl:with-param>
<!-- last element -->
<xsl:with-param name="c"><xsl:value-of
select="."/></xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</html>
</xsl:template>
<xsl:template name="test_template">
<xsl:param name="b"></xsl:param>
<xsl:param name="c"></xsl:param>
<xsl:value-of select="$b" />
<xsl:value-of select="$c" />
</xsl:template>
</xsl:stylesheet>
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
|
|