finding the minimum value of a set of data

P

Porthos

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

Martin Honnen

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

=?ISO-8859-1?Q?J=FCrgen_Kahrs?=

Porthos said:
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 }
 
D

Dimitre Novatchev

Porthos said:
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.
 
J

jacob.chaney

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,838
Latest member
KandiceChi

Latest Threads

Top