This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Maximum (Was Re: counting/comparing values)
- To: xsl-list at lists dot mulberrytech dot com
- Subject: [xsl] Maximum (Was Re: counting/comparing values)
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- Date: Fri, 9 Nov 2001 21:35:16 -0800 (PST)
- Reply-To: xsl-list at lists dot mulberrytech dot com
> I am stuck trying to get the highest number of child elements of a
> particular type. What I would like to do is return the count of the most
> <entry> elements within a single <row> of a <table>:
In January there was a thread in this group on the solution of exactly the same
problem.
Another, functional solution is the following:
maximum = foldl1 max
where foldl1 is a foldl function that is defined on non-empty lists
Here's a translation of this into XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:maximum-pick-bigger="f:maximum-pick-bigger"
xmlns:maximum-own-compare="f:maximum-own-compare"
exclude-result-prefixes="xsl maximum-own-compare maximum-pick-bigger"
>
<xsl:import href="foldl.xsl"/>
<maximum-pick-bigger:maximum-pick-bigger/>
<maximum-own-compare:maximum-own-compare/>
<xsl:template name="maximum">
<xsl:param name="pList" select="/.."/>
<xsl:param name="pCMPFun" select="/.."/>
<xsl:variable name="vdfCMPFun"
select="document('')/*/maximum-own-compare:*[1]"/>
<xsl:variable name="vFoldFun"
select="document('')/*/maximum-pick-bigger:*[1]"/>
<xsl:if test="$pList">
<xsl:variable name="vCMPFun" select="$pCMPFun |
$vdfCMPFun[not($pCMPFun)]"/>
<xsl:variable name="vFuncList">
<xsl:copy-of select="$vFoldFun"/> <!-- Pick Bigger -->
<xsl:copy-of select="$vCMPFun"/> <!-- Compare -->
</xsl:variable>
<xsl:call-template name="foldl">
<xsl:with-param name="pFunc" select="msxsl:node-set($vFuncList)/*"/>
<xsl:with-param name="pList" select="$pList"/>
<xsl:with-param name="pA0" select="$pList[1]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="pickBigger" match="maximum-pick-bigger:*">
<xsl:param name="arg0"/>
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>
<xsl:variable name="vIsGreater">
<xsl:apply-templates select="$arg0">
<xsl:with-param name="arg1" select="$arg1"/>
<xsl:with-param name="arg2" select="$arg2"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vIsGreater = 1">
<xsl:copy-of select="$arg1"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$arg2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="isGreaterDefault" match="maximum-own-compare:*">
<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>
This returns a copy of the "maximum" node. The caller may provide as parameters
their own function (template reference to a template) that returns 1 if the node
passed as "arg1" to it is the "bigger" of the two nodes. In case the compared values
are numbers, no reference to an isGreater template needs to be provided and a
default internal one is used.
The XSLT implementation of foldl is available at:
http://sources.redhat.com/ml/xsl-list/2001-11/msg00214.html
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list