This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: max value


> Hello,
> Is there a way to get the max value .
> 
> something that would look like and returns "11"
> 
> <xsl:template match="values">
>       <xsl:value-of select="max(value)" />
> </xsl:template>
> 
> <values>
>    <value>7</value>
>    <value>11</value>
>    <value>8</value>
>    <value>4</value>
> </values>

You don't have to wait for a specific vendor to implement some new "features" of
Exslt, nor have you to wait for XSLT 2.0.

Just grab and use this immediately ***now***:

http://sources.redhat.com/ml/xsl-list/2001-11/msg00407.html


This is a functional-programming style implementation of max(), where the comparison
function is passed to the standard max() template as a parameter.

This (like  sumAndTransform) gives a general solution to all class of max/min
problems, in which the ordering relation may not be the most common "<" and the
elements may not be "just numbers".

Using the standard max() function from the standard functional-programming XSLT
library, you'll simply need one minute (an experienced XSLT programmer may need 15
minutes to write and debug from scratch a new recursive template, a newbie may not
succeed to do this in a single day) to write the following:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:maximum-own-compare="maximum-own-compare"
xmlns:Mycompare="Mycompare"
exclude-result-prefixes="xsl Mycompare"
>
   <xsl:import href="maximum.xsl"/>
   
   <xsl:output method="text"/>
   <Mycompare:Mycompare/>

    <xsl:template match="/">
      <xsl:variable name="vCMPFun" select="document('')/*/Mycompare:*[1]"/>

      <xsl:call-template name="maximum">
        <xsl:with-param name="pList" select="/*/*"/>
        <xsl:with-param name="pCMPFun" select="$vCMPFun"/> 

      </xsl:call-template>
    </xsl:template>

    <xsl:template name="MyIsGreater" match="*[namespace-uri() = 'Mycompare']">
         <xsl:param name="arg1"/>
         <xsl:param name="arg2"/>

         <xsl:choose>
          <xsl:when test="$arg1 > $arg2">1</xsl:when>
          <xsl:otherwise>0</xsl:otherwise>
         </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Or you can even omit the "MyIsGreater" template, because the standard max() template
has a default comarison, in case it is not specified by the caller:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
   <xsl:import href="maximum.xsl"/>
   <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:call-template name="maximum">
        <xsl:with-param name="pList" select="/*/*"/>

      </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>

In both cases, when applied to the following (your) source xml:

<values>
   <value>7</value>
   <value>11</value>
   <value>8</value>
   <value>4</value>
</values>

These two transformations return the same correct answer:
11.

The max() function is so powerful, because it accepts a user-supplied comparison
function as a parameter -- that is, max() is a higher order function.

This gives us countless possibilities for reuse. One example is to build the min()
function. To do this, we have just to change a single line in our "MyIsGreater"
template:

replacing:

          <xsl:when test="$arg1 > $arg2">1</xsl:when>
with

          <xsl:when test="$arg1 &lt; $arg2">1</xsl:when>

in the "MyIsGreater" template above,

will reverse the comparison and the result of the transformation will now be:

4

Or, you could easily make it find the maximum of hexadecimal numbers, or numbers
coded in some special way that makes them not standard XSLT numbers (but NaN
instead). 

As shown in

http://sources.redhat.com/ml/xsl-list/2001-11/msg00407.html

this powerful function is based on an even more powerful and generic function
"foldl", which is a generic higher-order function that applies any
parameter-function (operation) on the elements of a list and accumulates the effect
of these applications.

In this way we get multitude of useful functions -- sum, product, map, append,
reverse, sum-of-products, ... etc., ... etc.

Any non-functional-based standard library will need many years and numerous releases
in order to provide just a specific subset of these functions and will still be
incomplete -- at a cost of an effort that could be prohibitively large when compared
to a library of higher-order functions.

I have produced the XSLT 1.0 implementations of some of the most important
list-processing functions from the Haskell Prelude, plus other functions.

I'd be glad to make these freely available soon.

Cheers,
Dimitre Novatchev.






__________________________________________________
Do You Yahoo!?
Check out Yahoo! Shopping and Yahoo! Auctions for all of
your unique holiday gifts! Buy at http://shopping.yahoo.com
or bid at http://auctions.yahoo.com

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]