Re: [xsl] Trying to identify the 3 highest sales results

Subject: Re: [xsl] Trying to identify the 3 highest sales results
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Mon, 7 Jan 2008 06:06:32 -0800
> I think any more efficient solution involves first doing a sort to identify
> the top three, and storing this data in some temporary data structure for
> reference while you generate the output. 2-phase solutions in XSLT 1.0
> invariably require the xx:node-set() extension.

Theoretically, one could do this in linear time, by finding first the
maximum of all sales, then the maximum of the rest and then again the
maximum of the rest. We know how to implement finding the maximum in
O(N) using either straight recursion or DVC.

This approach can be implemented by not having to resort to the use of
xxx:node-set().

In practice, however, a single sort (O(N*log2(N)) is almost always
faster than the chain of several findings of maximum.



-- 
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play



On Jan 7, 2008 2:15 AM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> A crude approach would be along the lines:
>
> <xsl:attribute name="class">
>  <xsl:variable name="numAbove" select="count(../row/agent[sales >
> current()/sales])"/>
>  <xsl:choose>
>    <xsl:when test="$numAbove=0">first</xsl:when>
>    <xsl:when test="$numAbove=1">second</xsl:when>
>    <xsl:when test="$numAbove=2">third</xsl:when>
>    <xsl:otherwise>...</xsl:otherwise>
>
> That's likely to be O(n^2) in performance, so it's only viable with modest
> amounts of data.
>
> I think any more efficient solution involves first doing a sort to identify
> the top three, and storing this data in some temporary data structure for
> reference while you generate the output. 2-phase solutions in XSLT 1.0
> invariably require the xx:node-set() extension.
>
> A compromise would be for your first pass to return a single number, the
> sales achieved by the third-highest agent, and then do the logic above only
> if the sales are >= this figure. You can then do the first pass as
>
> <xsl:variable name="third-highest">
>  <xsl:for-each select="row">
>    <xsl:sort select="sales" data-type="number" order="descending"/>
>    <xsl:if test="position()=3"><xsl:value-of select="sales"/></xsl:if>
>  </
> </
>
> or you could do the above three times to initialize three variables.
>
> In 2.0 you can do
>
> <xsl:variable name="sales-ranked" as="xs:integer">
>  <xsl:perform-sort select="row/sales"/>
>    <xsl:sort select="number(.)" order="descending"/>
>
> Then
>
> <xsl:for-each select="row">
>  <td class="{if (sales=$sales-ranked[1]) then 'first'
>                else if (sales=$sales-ranked[2]) then 'second'
> etc
>
> Michael Kay
> http://www.saxonica.com/
>
>
> > -----Original Message-----
> > From: Arthur Maloney [mailto:ArthurM@xxxxxxxxxx]
> > Sent: 07 January 2008 07:21
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: [xsl] Trying to identify the 3 highest sales results
> >
> > Hello xsl-list,
> >
> >  I'm using Xslt(v1.0) to convert an Xml(v1.0) file to Xhtml
> > for browser display  and trying to add a visual for the top 3
> > sales result.
> >
> >  i.e. trying to build
> >  <td class="first">9</td>
> >  <td class="second">6</td>
> >  <td class="third">3</td>
> >  The CSS class translates to <img src="boldGold.gif"
> > alt="first" />  I'm Ok with building the Xhtml and adding CSS classes
> >
> >  When the row template is being processed.
> >  How Do you Identify if it's the 1st, 2nd or 3rd highest sales figure?
> >  Typically there are 200-300 salesmen results per calculation
> > and the Xml  by design,is pre sorted by salesman name.
> >
> >
> > Xslt shard
> >  <xsl:template match="row">
> >       <tr>
> >       ...
> >       <td>
> >         <xsl:value-of select="sales"/>
> >       </td>
> >       </tr>
> > </xsl:template>
> >
> >
> > Xml shard
> > <table calculated="08W021T07:16">
> >    <row>
> >       <agent>Fred Smith</agent>
> >       ...
> >       <sales>6</sales>
> >    </row>
> >    <row>
> >       <agent>George Jones</agent>
> >       ...
> >       <sales>9</sales>
> >    </row>
> >    <row>
> >       <agent>George Jones Jr</agent>
> >       ...
> >       <sales>1</sales>
> >    </row>
> >    <row>
> >       <agent>Karina Houseman</agent>
> >       ...
> >       <sales>3</sales>
> >    </row>
> > </table>
> >
> >
> > --
> > Best regards,
> >  Arthur                          mailto:ArthurM@xxxxxxxxxx

Current Thread