finding the minimum value of a set of data

Discussion in 'XML' started by Porthos, Jan 19, 2005.

  1. Porthos

    Porthos Guest

    Hi All,

    I'm trying to find the minimum value of a set of data (see below).
    I want to compare the lengths of these attribute values and display
    the lowest one.

    This would be simple if I could re-assign values to a variable,
    but from what I gather I can't do that. How do I keep track of the
    lowest value as I loop through? My XSL document only finds the length
    of each string and prints it out (for now). I can write a template
    that calls itself for recursion, but I don't know how to keep the
    minimum value readially available as I go through each loop.

    Thanks,

    James

    XML Document
    =============================
    <calendar name="americana">
    <month value="January"/>
    <month value="February"/>
    <month value="March"/>
    <month value="April"/>
    <month value="May"/>
    <month value="June"/>
    <month value="July"/>
    <month value="August"/>
    <month value="September"/>
    <month value="October"/>
    <month value="November"/>
    <month value="December"/>
    </calendar>

    XSL Document (so far)
    =============================
    <xsl:template match="/">
    <xsl:for-each select="calendar/month">
    <xsl:call-template name="find_min_max">
    <xsl:with-param name="min" select="string-length(@value)"/>
    </xsl:call-template>
    </xsl:for-each>
    </xsl:template>

    <xsl:template name="find_min_max">
    <xsl:param name="min" select="0"/>
    <xsl:value-of select="$min"/>

    <br/>
    </xsl:template>
     
    Porthos, Jan 19, 2005
    #1
    1. Advertising

  2. Porthos wrote:


    > I'm trying to find the minimum value of a set of data (see below).
    > I want to compare the lengths of these attribute values and display
    > the lowest one.


    > XML Document
    > =============================
    > <calendar name="americana">
    > <month value="January"/>
    > <month value="February"/>
    > <month value="March"/>
    > <month value="April"/>
    > <month value="May"/>
    > <month value="June"/>
    > <month value="July"/>
    > <month value="August"/>
    > <month value="September"/>
    > <month value="October"/>
    > <month value="November"/>
    > <month value="December"/>
    > </calendar>


    With the following stylesheet

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:eek:utput method="xml" indent="yes" />

    <xsl:template match="/">
    <result>
    <xsl:call-template name="find-min-string">
    <xsl:with-param name="nodes" select="calendar/month/@value" />
    </xsl:call-template>
    </result>
    </xsl:template>

    <xsl:template name="find-min-string">
    <xsl:param name="nodes" />
    <xsl:param name="min" select="''" />
    <xsl:variable name="head" select="$nodes[1]" />
    <xsl:variable name="tail" select="$nodes[position() &gt; 1]" />
    <xsl:variable name="current-min">
    <xsl:choose>
    <xsl:when test="$min != '' and string-length($min) &lt;
    string-length($head)">
    <xsl:value-of select="$min" />
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of select="$head" />
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:variable>
    <xsl:choose>
    <xsl:when test="$tail">
    <xsl:call-template name="find-min-string">
    <xsl:with-param name="nodes" select="$tail" />
    <xsl:with-param name="min" select="$current-min" />
    </xsl:call-template>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:copy-of select="$current-min" />
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

    the output is

    <result>May</result>


    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Jan 19, 2005
    #2
    1. Advertising

  3. Porthos wrote:

    > I'm trying to find the minimum value of a set of data (see below).
    > I want to compare the lengths of these attribute values and display
    > the lowest one.


    If your intention really is to print the minimum
    value, then it is not necessary to use XSL. Any
    other tool like XMLgawl will also do. This one
    is tested and works:

    BEGIN { XMLMODE=1; OFS= "\t" }

    XMLSTARTELEM == "month" {
    # Initialize shortest
    if (shortest == "")
    shortest = XMLATTR["value"]
    # Find shortest value
    if (length(XMLATTR["value"]) < length(shortest))
    shortest = XMLATTR["value"]
    }

    END { print shortest }
     
    =?ISO-8859-1?Q?J=FCrgen_Kahrs?=, Jan 19, 2005
    #3
  4. "Porthos" <> wrote in message
    news:...
    > Hi All,
    >
    > I'm trying to find the minimum value of a set of data (see below).
    > I want to compare the lengths of these attribute values and display
    > the lowest one.
    >
    > This would be simple if I could re-assign values to a variable,
    > but from what I gather I can't do that. How do I keep track of the
    > lowest value as I loop through? My XSL document only finds the length
    > of each string and prints it out (for now). I can write a template
    > that calls itself for recursion, but I don't know how to keep the
    > minimum value readially available as I go through each loop.
    >
    > Thanks,
    >
    > James


    In XSLT 2.0 + FXSL the result is obtained by the following one-liner:

    data(/*/*/@*
    [string-length(.)
    =
    min(f:map(f:string-length(),/*/*/@*))]
    )


    The complete transformation is:

    <xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:f="http://fxsl.sf.net/"
    exclude-result-prefixes="f"
    >

    <xsl:import href="../f/func-standardXpathFunctions.xsl"/>
    <xsl:import href="../f/func-map.xsl"/>

    <xsl:eek:utput method="text"/>

    <xsl:template match="/">
    <xsl:sequence select=
    "data(/*/*/@*
    [string-length(.)
    =
    min(f:map(f:string-length(),/*/*/@*))]
    )"
    />
    </xsl:template>
    </xsl:stylesheet>


    When applied on your source xml document, this transformation produces the
    wanted result:

    May


    It also will produce the list of all minimal values if there is more than
    one minimal value.


    Cheers,

    Dimitre Novatchev.




    >
    > XML Document
    > =============================
    > <calendar name="americana">
    > <month value="January"/>
    > <month value="February"/>
    > <month value="March"/>
    > <month value="April"/>
    > <month value="May"/>
    > <month value="June"/>
    > <month value="July"/>
    > <month value="August"/>
    > <month value="September"/>
    > <month value="October"/>
    > <month value="November"/>
    > <month value="December"/>
    > </calendar>
    >
    > XSL Document (so far)
    > =============================
    > <xsl:template match="/">
    > <xsl:for-each select="calendar/month">
    > <xsl:call-template name="find_min_max">
    > <xsl:with-param name="min" select="string-length(@value)"/>
    > </xsl:call-template>
    > </xsl:for-each>
    > </xsl:template>
    >
    > <xsl:template name="find_min_max">
    > <xsl:param name="min" select="0"/>
    > <xsl:value-of select="$min"/>
    >
    > <br/>
    > </xsl:template>
    >
     
    Dimitre Novatchev, Jan 19, 2005
    #4
  5. Porthos

    Guest

    James,

    This is an off topic response to your post but I too am looking into
    the CycleTrak motorcyle tracking system and saw your post on google
    groups. I was wondering if you ever purchased it or had any experience
    with it that you would care to share with me? Thank you in advance.
    Jacob
    Porthos wrote:
    > Hi All,
    >
    > I'm trying to find the minimum value of a set of data (see below).
    > I want to compare the lengths of these attribute values and display
    > the lowest one.
    >
    > This would be simple if I could re-assign values to a variable,
    > but from what I gather I can't do that. How do I keep track of the
    > lowest value as I loop through? My XSL document only finds the

    length
    > of each string and prints it out (for now). I can write a template
    > that calls itself for recursion, but I don't know how to keep the
    > minimum value readially available as I go through each loop.
    >
    > Thanks,
    >
    > James
    >
    > XML Document
    > =============================
    > <calendar name="americana">
    > <month value="January"/>
    > <month value="February"/>
    > <month value="March"/>
    > <month value="April"/>
    > <month value="May"/>
    > <month value="June"/>
    > <month value="July"/>
    > <month value="August"/>
    > <month value="September"/>
    > <month value="October"/>
    > <month value="November"/>
    > <month value="December"/>
    > </calendar>
    >
    > XSL Document (so far)
    > =============================
    > <xsl:template match="/">
    > <xsl:for-each select="calendar/month">
    > <xsl:call-template name="find_min_max">
    > <xsl:with-param name="min" select="string-length(@value)"/>
    > </xsl:call-template>
    > </xsl:for-each>
    > </xsl:template>
    >
    > <xsl:template name="find_min_max">
    > <xsl:param name="min" select="0"/>
    > <xsl:value-of select="$min"/>
    >
    > <br/>
    > </xsl:template>
     
    , Jan 31, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joey
    Replies:
    2
    Views:
    808
  2. Adam H. Peterson
    Replies:
    17
    Views:
    684
    Adam H. Peterson
    Sep 29, 2003
  3. pmatos
    Replies:
    18
    Views:
    534
    Steven T. Hatton
    Jun 26, 2005
  4. Rui Maciel
    Replies:
    2
    Views:
    3,265
    AndrewDover
    Dec 1, 2009
  5. Pugi!
    Replies:
    2
    Views:
    117
    Steve
    Feb 12, 2007
Loading...

Share This Page