Re: Getting the first and last nodes of a sorted nodeset
2004-04-08 08:56:25
John,
Having just posted, I should add:
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.
This stated requirement doesn't look to me like it should be so hard in
principle, so what I described as option 1 (pure XSLT 1.0 solution) should
be manageable. Accomplishing it might require inverting your description of
the problem: instead of "get[ting] a sorted list of dates and generating
output for all dates from the first to last", think of getting an unsorted
list of dates and a pair of dates (first and last), and reporting all dates
you have that fall between the first and last, and sorting them.
Or perhaps I should be reading more deeply into your hint "whether they
appear in the original XML or not". Are you actually asking for how to
generate a list of dates *from scratch*, in order, given only a start point
and an end point? This is also doable in XSLT 1.0, though it would have to
use a couple of advanced methods (specifically you may need one or more
recursive templates).
Please clarify.
Cheers,
Wendell
At 11:10 AM 4/8/2004, you wrote:
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
======================================================================
--+------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--+--
======================================================================
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
======================================================================
|
|