2009-02-17 8 views
1

Je suis coincé avec un problème qui semble stupide mais je ne trouve pas la solution ... Avec XLST, j'ai besoin de sommer une liste de valeurs calculées par un template. J'ai donc stocké ces valeurs dans une arborescence (une liste d'éléments "Number" contenus dans un élément racine "Numbers"). Mais quoi que j'essaie de faire avec cette liste self-made, il ne retournera rien, 0 ou une erreur ...XSLT: la somme du fragment d'arbre retournera toujours 0!

Est-ce que quelqu'un sait ce que je fais mal?

<!-- create the tree fragment --> 
<xsl:variable name="_subTotals"> 
    <Numbers> 
     <xsl:for-each select="List"> 
      <xsl:variable name="_Size"> 
       <xsl:call-template name="GetSize"> 
        <xsl:with-param name="_value" select="@value"/> 
       </xsl:call-template> 
      </xsl:variable> 
      <Number> 
       <xsl:value-of select="$_Size"/> 
      </Number> 
     </xsl:for-each> 
    </Numbers> 
</xsl:variable> 

<!-- this returns an error: expression must result into a node-set --> 
<xsl:message terminate="no"> 
    <xsl:value-of select="sum($_subTotals/Numbers/Number)"/> 
</xsl:message> 

<!-- transform the tree fragment into a node-set 
<xsl:variable name="_Total" select="msxsl:node-set($_subTotals)"/> 

<!-- returns nothing --> 
<xsl:for-each select="$_Total/Numbers/Number"> 
    <xsl:message terminate="no"> 
     <xsl:value-of select="@value"/> 
    </xsl:message> 
</xsl:for-each> 

<!-- returns 0 --> 
<xsl:value-of select="sum($_Total/Numbers/Number)"/> 

Répondre

0

Voici un moyen rapide d'additionner des valeurs générées dynamiquement (Le modèle que vous appelez ne produit probablement pas les résultats attendus?) Si oui, vous devez poser une autre question et fournir le code et le document XML . dont le code fonctionne sans ceux-ci ne peut aider et suppositions ne seraient pas utiles).

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

    <xsl:template match="/"> 
     <xsl:variable name="vrtfNums"> 
     <nums> 
      <num>1</num> 
      <num>2</num> 
     </nums> 
     </xsl:variable> 

     <xsl:variable name="vNums" select="ext:node-set($vrtfNums)"/> 

     <xsl:value-of select="sum($vNums/*/*)"/> 
    </xsl:template> 
</xsl:stylesheet> 

Lorsque la transformation ci-dessus est appliquée sur tout document XML (ignoré), le résultat recherché est produit:

3 
0

Merci beaucoup Dimitre! C'est exactement ce qui a résolu mon problème: l'expression X-Path que j'ai utilisée dans la fonction sum.

Mais pourquoi ce travail:

<xsl:value-of select="sum($vNums/*/*)"/> 

et non que:

<xsl:value-of select="sum($vNums/nums/num)"/> 

?

0

La récursivité est la réponse habituelle dans les langages fonctionnels. Quelque chose comme:

<xsl:template name='totalRest> 
    <xsl:variable nane='sub'> 
    <!-- Use for-each to set local new context node --> 
    <xsl:for-each select='following::List[1]'> 
     <xsl:call-template name='totalRest'/> 
    </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name='this'> 
    <xsl:call-template name="GetSize"> 
     <xsl:with-param name="_value" select="@value"/> 
    </xsl:call-template> 
    </xsl:variable> 

    <xsl:value-of select='$sub+$this' /> 

</xsl:template> 

Sans savoir plus GetSize et le document d'entrée, il est difficile d'être plus précis sur le droit XPath pour définir le nœud de contexte pour l'appel récursif.

+0

Désolé de ne pas être très précis, mais j'ai essayé de simplifier le problème. En fait, j'utilise un attribut des éléments List comme ID pour obtenir d'autres valeurs d'attribut quelque part dans le document d'entrée, qui sont alors les paramètres (il y en a 3) du modèle GetSize. – Julien

+0

Mais merci pour votre réponse, Richard! Je vais essayer de l'implémenter. – Julien

+0

L'approche de récursivité est générale, cependant les détails (et assurant le noeud de contexte pour XPath est OK) et le rendent arbitrairement complexe :-( – Richard

Questions connexes