xsl-list
[Top] [All Lists]

RE: Need your help

2005-05-04 16:41:20
Marco,

Given your XML:


<company>
  <division DID="SAL">
     <projects>
        <project PID="SAL1">
           <BUDGET>100000</BUDGET>
        </project>
        <project PID="SAL2">
           <BUDGET>2000000</BUDGET>
        </project>
        <project PID="SAL2">
           <BUDGET>2000000</BUDGET>
        </project>
     </projects>
  </division>
  <division DID="ENG">
     <projects>
        <project PID="ENG1">
           <BUDGET>1985555</BUDGET>
        </project>
        <project PID="ENG2">
           <BUDGET>3000000</BUDGET>
        </project>
        <project PID="ENG3">
           <BUDGET>4000000</BUDGET>
        </project>
        Etc...
     </projects>
   Etc...
</company>

The following XSL demonstrates 3 ways of getting the max.

<?xml version="1.0" encoding="iso8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
   <xsl:output method="text"/>

   <xsl:template match="/">
       <xsl:for-each select="company/division">
           <xsl:sort select="@DID"/>
           <xsl:apply-templates select="."/>
           <xsl:text>=============================&#xa;</xsl:text>
       </xsl:for-each>
   </xsl:template>

   <xsl:template match="division">
       <xsl:for-each select="projects/project">
           <xsl:sort select="@PID"/>
<xsl:value-of select="concat('PID=', @PID, ' Budget=', BUDGET, '&#xa;')"/>
       </xsl:for-each>

       <xsl:text>max-by-sort=</xsl:text>
       <xsl:call-template name="max-by-sort">
           <xsl:with-param name="nodes" select="projects/project"/>
       </xsl:call-template>
       <xsl:text>&#xa;</xsl:text>

       <xsl:text>max-by-tail-recursion=</xsl:text>
       <xsl:call-template name="max-by-tail-recursion">
           <xsl:with-param name="nodes" select="projects/project/BUDGET"/>
       </xsl:call-template>
       <xsl:text>&#xa;</xsl:text>

       <xsl:text>max-by-recursion=</xsl:text>
       <xsl:call-template name="max-by-recursion">
           <xsl:with-param name="nodes" select="projects/project/BUDGET"/>
       </xsl:call-template>
       <xsl:text>&#xa;</xsl:text>
   </xsl:template>

   <xsl:template name="max-by-sort">
       <xsl:param name="nodes" select="/.."/>

       <xsl:for-each select="$nodes">
           <xsl:sort select="BUDGET"/>
           <xsl:if test="position() = last()">
               <xsl:value-of select="BUDGET"/>
           </xsl:if>
       </xsl:for-each>
   </xsl:template>


   <xsl:template name="max-by-tail-recursion">
       <!--Use a parameter to hold all the values -->
       <xsl:param name="nodes" select="/.."/>
       <xsl:param name="max" select="0"/>

       <xsl:choose>
           <xsl:when test="$nodes">
               <xsl:call-template name="max-by-tail-recursion">
<xsl:with-param name="nodes" select="$nodes[position() != 1]"/>
                   <xsl:with-param name="max">
                       <xsl:choose>
                           <xsl:when test="$max &gt; $nodes[1]">
                               <xsl:value-of select="$max"/>
                           </xsl:when>
                           <xsl:otherwise>
                               <xsl:value-of select="$nodes[1]"/>
                           </xsl:otherwise>
                       </xsl:choose>
                   </xsl:with-param>
               </xsl:call-template>
           </xsl:when>
           <xsl:otherwise>
               <xsl:value-of select="$max"/>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>


   <xsl:template name="max-by-recursion">
       <xsl:param name="nodes" />
       <xsl:choose>
           <xsl:when test="$nodes">
               <xsl:variable name="max-of-rest">
                   <xsl:call-template name="max-by-recursion">
                       <xsl:with-param name="nodes"
                               select="$nodes[position()!=1]" />
                   </xsl:call-template>
               </xsl:variable>

               <xsl:choose>
                   <xsl:when test="$nodes[1] > $max-of-rest">
                       <xsl:value-of select="$nodes[1]" />
                   </xsl:when>
                   <xsl:otherwise>
                       <xsl:value-of select="$max-of-rest" />
                   </xsl:otherwise>
               </xsl:choose>
           </xsl:when>

           <xsl:otherwise>
               <xsl:value-of select="0" />
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>


</xsl:stylesheet>


When applied it yields this:

PID=ENG1 Budget=1985555
PID=ENG2 Budget=3000000
PID=ENG3 Budget=4000000
max-by-sort=4000000
max-by-tail-recursion=4000000
max-by-recursion=4000000
=============================
PID=SAL1 Budget=100000
PID=SAL2 Budget=2000000
PID=SAL2 Budget=2000000
max-by-sort=2000000
max-by-tail-recursion=2000000
max-by-recursion=2000000
=============================

max-by-recursion is the approach you were trying for, it seems. Please note that htere are freely useable libraries that do this sort of thing--sorting, grouping, etc. The exsl project has implementations, for example.


Regards,

--A


Here is my xlst code so far:

I call the routine in this manner, set in a <xsl:for-each
select="company/division">:

<xsl:call-template name="max">
  <!--Pass the BUDGET values into the max routine using the pararmeter
BudgetValues-->
  <xsl:with-param name="BudgetValues" select="projects/project/BUDGET"/>
</xsl:call-template>

Here is the recursive routine:

<xsl:template name="max">
  <!--Use a parameter to hold all the values -->
  <xsl:param name="BudgetValues"/>
     <xsl:text>Passing in the values</xsl:text><p/>
         <xsl:choose>
            <!--Test to see if the node-set is empty -->
           <xsl:when test="$BudgetValues">
            <!--Get the first value of Budget -->
            <xsl:variable name="firstValue" select="$BudgetValues[1]"/>
            <!--Cycle through the rest of the values and place them in a
variable (max-of-rest)
                  By calling the template max
          -->
            <xsl:variable name="max-of-rest">
                 <xsl:call-template name="max">
                   <xsl:with-param name="BudgetValues"
select="$BudgetValues[position() != 1]"/>

                 </xsl:call-template>
           </xsl:variable>
           <xsl:choose>
           <!--Is the first Vlaue greater then the max-of-rest then select
firstValue -->
           <xsl:when test="$firstValue &gt; $max-of-rest">
                <xsl:value-of select="$firstValue"/>
                <xsl:text>Got to the first value</xsl:text>
           </xsl:when>
           <!--If not then select the max-of-rest -->
           <xsl:otherwise>
                <xsl:value-of select="$max-of-rest"/>
                <xsl:text>Got to the last value</xsl:text>
           </xsl:otherwise>
           </xsl:choose>
           </xsl:when>
           <!--If I get this value it the routine is incorrect -->
            <xsl:otherwise><xsl:text>This is the wrong value
</xsl:text>0<p/></xsl:otherwise>
                </xsl:choose>
                </xsl:template>


The sample of the output is shown (for three budget values for the PID
division):

PID : MAR1 Project Name: Marketing Project 1 Budget: 3200000
PID : SAL1 Project Name: Sales Project 1 Budget: 1000000
PID : RES1 Project Name: Research Project 1 Budget: 100000

The maximum budget value is
Passing in the values

Passing in the valuesPassing in the valuesPassing in the valuesThis is the
wrong value 0Got to the last valueGot to the last valueGot to the last value


I wish to obtain the maximum value BUDGET value for each division, for the
projects in each division.

That is for division SAL, maximum budget value is 2000000.
That is for division ENG, maximum budget value is 4000000.

_________________________________________________________________
Don?t just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/


--~------------------------------------------------------------------
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>
--~--



<Prev in Thread] Current Thread [Next in Thread>
  • RE: Need your help, Aron Bock <=