On peut utiliser le modèle "maximum" tel que fourni par FXSL -- the Functional Programming Library for XSLT. FXSL est entièrement écrit en XSLT lui-même.
Voici un exemple d'utilisation du modèle "maximum":
Lorsque cette transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:maximum-own-compare="maximum-own-compare"
xmlns:Mycompare="Mycompare"
exclude-result-prefixes="xsl f Mycompare"
>
<xsl:import href="maximum.xsl"/>
<xsl:output method="text"/>
<!-- This transformation must be applied to:
numList.xml
-->
<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" mode="f:FXSL"
match="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>
est appliqué sur ce document XML:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
le résultat recherché est obtenu .
10
Notez que je peux passer n'importe quelle opération de "comparaison" nécessaire comme paramètre! Par exemple, si mon opération de comparaison renvoie 1 lorsque $ arg1 < $ arg2, la transformation ci-dessus produira "01" - le minimum de toutes les valeurs.
Maintenant, je vais montrer deux solutions pour le problème original.
Solution1 (à l'aide du modèle "maximum" de la FXSL):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:Mycompare="Mycompare"
exclude-result-prefixes="xsl f Mycompare"
>
<xsl:import href="maximum.xsl"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<Mycompare:Mycompare/>
<xsl:variable name="vCMPFun"
select="document('')/*/Mycompare:*[1]"/>
<xsl:template match="/">
<persons>
<xsl:apply-templates select="*/*"/>
</persons>
</xsl:template>
<xsl:template match="person">
<person>
<xsl:call-template name="maximum">
<xsl:with-param name="pList" select="*/*"/>
<xsl:with-param name="pCMPFun" select="$vCMPFun"/>
</xsl:call-template>
</person>
</xsl:template>
<xsl:template name="MyIsGreater" mode="f:FXSL"
match="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>
Lorsque cette transformation est appliquée sur le document XML suivant:
<t>
<person>
<preferred-number>
<preferred-number>8</preferred-number>
<preferred-number>10</preferred-number>
<preferred-number>4</preferred-number>
<preferred-number>12</preferred-number></preferred-number>
</person>
<person>
<preferred-number>
<preferred-number>2</preferred-number>
<preferred-number>11</preferred-number>
<preferred-number>15</preferred-number>
<preferred-number>6</preferred-number></preferred-number>
</person>
<person>
<preferred-number>
<preferred-number>10</preferred-number>
<preferred-number>44</preferred-number>
<preferred-number>9</preferred-number></preferred-number>
</person>
</t>
le résultat recherché est produit:
<persons>
<person>
<preferred-number>12</preferred-number>
</person>
<person>
<preferred-number>15</preferred-number>
</person>
<person>
<preferred-number>44</preferred-number>
</person>
</persons>
Solution2 (en utilisant un modèle écrit à la main):
Lorsque cette transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<persons>
<xsl:apply-templates select="*/*"/>
</persons>
</xsl:template>
<xsl:template match="person">
<person>
<xsl:call-template name="maximum">
<xsl:with-param name="pList" select="*/*"/>
</xsl:call-template>
</person>
</xsl:template>
<xsl:template name="maximum">
<xsl:param name="pList"/>
<xsl:choose>
<xsl:when test="not($pList)">
-99999999999999999999
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vLen" select="count($pList)"/>
<xsl:choose>
<xsl:when test="$vLen = 1">
<xsl:value-of select="$pList[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vHalf"
select="floor($vLen div 2)"/>
<xsl:variable name="vMax1">
<xsl:call-template name="maximum">
<xsl:with-param name="pList"
select="$pList[not(position() > $vHalf)]"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vMax2">
<xsl:call-template name="maximum">
<xsl:with-param name="pList"
select="$pList[position() > $vHalf]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of
select="$vMax1*($vMax1 > $vMax2)
+
$vMax2*($vMax2 >= $vMax1)
"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
est appliqué sur le même document XML, encore une fois le résultat correct est produit:
<persons>
<person>12</person>
<person>15</person>
<person>44</person>
</persons>
Dayron, voir ma réponse contenant deux solutions différentes à votre problème. –