2010-08-02 61 views
8

¿Cómo puedo encontrar los 2 números más grandes de 3 números y realizar algunas operaciones aritméticas en ellos como en el siguiente ejemplo?operación aritmética en XSLT

<root> 
    <num>10</num> 
    <num>12</num> 
    <num>8</num> 
</root> 

Para la entrada por encima del código XSLT debe mostrar "10 + 12 = 22" y "media = 11".

+1

Esto suena como tarea. ASÍ QUE la gente tiende a ignorar las preguntas tipo "dame la respuesta". ¿Qué has intentado? Muestra lo que has hecho y lo que no funciona. –

+0

@Jim Garrisson: ¡No sé cómo hacer operaciones aritméticas en xslt! este no es mi trabajo a domicilio. – brainless

+1

@Jim Garrisson: mi problema es mucho más grande. He dado solo un pequeño fragmento de código, por ejemplo. y yo no soy un niño de escuela – brainless

Respuesta

14

Esta hoja de estilo:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="/root"> 
     <xsl:variable name="max1" select="num[not(../num > .)]"/> 
     <xsl:variable name="max2" select="num[not(../num[count(.|$max1)!=1] > .)]"/> 
     <xsl:value-of select="concat($max1,' + ', 
            $max2,' = ', 
            $max1 + $max2,'&#xA;', 
            'average = ', 
            ($max1 + $max2) div 2,'&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 

de salida:

12 + 10 = 22 
average = 11 
9

I. XSLT 1.0 solución

Esta transformación se encuentra la suma y el promedio de todos los números excepto aquellos con el mínimo valor - funciona para un conjunto de nodos de cualquier longitud:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:variable name="vMin"> 
    <xsl:for-each select="/*/num"> 
    <xsl:sort data-type="number"/> 
    <xsl:if test="position()=1"> 
    <xsl:value-of select="."/> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:variable> 

<xsl:variable name="vNumsWithoutMin" select="/*/num[not(.=$vMin)]"/> 

<xsl:variable name="vSumWithoutMin" select="sum($vNumsWithoutMin)"/> 

<xsl:template match="/*"> 
    <xsl:apply-templates select="$vNumsWithoutMin"/> 
    <xsl:value-of select="concat(' = ', $vSumWithoutMin)"/> 
    average = <xsl:value-of select= 
    "$vSumWithoutMin div count($vNumsWithoutMin)"/> 
</xsl:template> 

<xsl:template match="num"> 
    <xsl:value-of select="."/> 
    <xsl:if test="not(position()=last())"> 
    <xsl:text> + </xsl:text> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

Cuando esto se aplica en el documento XML proporcionado:

<root> 
    <num>10</num> 
    <num>12</num> 
    <num>8</num> 
</root> 

el resultado deseado, se produce correcta:

10 + 12 = 22 
average = 11 

II. Solución XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output method="text"/> 

<xsl:variable name="vMin" select="min(/*/num/number(.))"/> 

<xsl:variable name="vNumsSansMin" 
    select="/*/num[not(number() eq $vMin)]/number(.)"/> 
<xsl:variable name="vAvgSansMin" 
     select="avg($vNumsSansMin)"/> 

<xsl:template match="/*"> 
    <xsl:sequence select= 
    "(for $i in 1 to count($vNumsSansMin) 
     return 
     ($vNumsSansMin[$i], 
      if(not($i eq count($vNumsSansMin))) 
      then ' + ' 
      else() 
     ) 
    ), 
     ' = ', sum($vNumsSansMin) 
    "/> 

    average = <xsl:sequence select="$vAvgSansMin"/> 
</xsl:template> 
</xsl:stylesheet>