2010-12-08 49 views
3

Est-il possible d'effectuer une totalisation conditionnelle en xsl?Total cumulatif XSL

je l'échantillon XML suivant:

<?xml version="1.0" encoding="utf-8"?> 
<export> 
<stats set="1"> 
    <columns> 
    <column id="0"> 
     <sum>100</sum> 
    </column> 
    <column id="1"> 
     <sum>102</sum> 
    </column> 
    <column id="2"> 
     <sum>12</sum> 
    </column> 
    </columns> 
</stats> 
    <stats set="2"> 
    <columns> 
     <column id="0"> 
     <sum>100</sum> 
     </column> 
     <column id="1"> 
     <sum>101</sum> 
     </column> 
     <column id="2"> 
     <sum>19</sum> 
     </column> 
    </columns> 
    </stats> 
</export> 

Est-il possible de calculer le total de toutes les colonnes de chaque jeu stat où ils ne sont pas égaux entre eux? Donc, il génèrerait les éléments suivants:

   Set 1  Set 2  Diff(Set 1 - Set 2) 
Total (Diff) 114   120   -6 
column 2  102   101   1 
column 3  12   19   -7 

Ainsi, dans la colonne de sortie 1 sera omise comme la somme dans les deux séries de statistiques est le même.

Je peux obtenir mon xsl pour sortir les colonnes qui sont différentes mais ne savez pas comment les additionner et les mettre dans la rangée totale.

Un grand merci,

Andez

+0

Modifier votre message pour inclure votre XSL –

+0

Excellente question, +1. Voir ma réponse pour une solution complète et efficace et pour des explications détaillées. :) –

Répondre

1

Cette transformation (64 lignes):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:key name="kColByPosAndVal" match="column" 
    use="concat(count(preceding-sibling::*), 
       '+', 
       sum)"/> 
<xsl:key name="kIdByVal" match="column/@id" 
    use="."/> 

<xsl:template match="/*"> 
    <xsl:variable name="vsum1" select= 
    "sum(stats[@set=1]/*/column 
        [not(key('kColByPosAndVal', 
          concat(count(preceding-sibling::*), 
            '+', 
            sum) 
          )[2] 
         )])"/> 
    <xsl:variable name="vsum2" select= 
    "sum(stats[@set=2]/*/column 
        [not(key('kColByPosAndVal', 
          concat(count(preceding-sibling::*), 
            '+', 
            sum) 
          )[2] 
         )])"/> 

       Set 1   Set 2  Diff(Set 1 - Set 2) 
    Total (Diff) <xsl:text/> 
    <xsl:value-of select="$vsum1"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vsum2"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vsum1 -$vsum2"/> 
    <xsl:text>&#xA;</xsl:text> 

    <xsl:for-each select= 
    "*/*/column/@id 
     [generate-id() 
     = generate-id(key('kIdByVal',.)[1]) 
     ] 
     [not(key('kColByPosAndVal', 
       concat(count(../preceding-sibling::*), 
         '+', 
         ../sum) 
       )[2] 
      )]"> 
    <xsl:variable name="vcolSet1" select= 
    "/*/stats[@set=1]/*/column[@id=current()]/sum"/> 

    <xsl:variable name="vcolSet2" select= 
    "/*/stats[@set=2]/*/column[@id=current()]/sum"/> 
    Column <xsl:value-of select=".+1"/><xsl:text/> 
    <xsl:text>  </xsl:text> 
    <xsl:value-of select="$vcolSet1"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vcolSet2"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vcolSet1 -$vcolSet2"/> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni:

<export> 
<stats set="1"> 
    <columns> 
    <column id="0"> 
     <sum>100</sum> 
    </column> 
    <column id="1"> 
     <sum>102</sum> 
    </column> 
    <column id="2"> 
     <sum>12</sum> 
    </column> 
    </columns> 
</stats> 
    <stats set="2"> 
    <columns> 
     <column id="0"> 
     <sum>100</sum> 
     </column> 
     <column id="1"> 
     <sum>101</sum> 
     </column> 
     <column id="2"> 
     <sum>19</sum> 
     </column> 
    </columns> 
    </stats> 
</export> 

produit le résultat souhaité, correct:

    Set 1   Set 2  Diff(Set 1 - Set 2) 
    Total (Diff) 114    120    -6 

    Column 2  102    101    1 

    Column 3  12    19    -7 

Explication:

  1. La clé nommée permet de sélectionner toutes les colonnes qui ont une position donnée (parmi tous column frères et sœurs) et une valeur donnée pour leur élément enfant sum.

  2. La clé nommée kIdByVal est utilisé dans le regroupement Muenchian pour trouver toutes les différentes valeurs pour l'attribut id.

  3. Les deux totaux sont calculés additionnant uniquement les colonnes dont sélectionne seulement une clé d'élément column (si elle sélectionne deux column éléments, ils sont tous deux à la même position et la même sum).

  4. Le reste devrait être facile à comprendre.

+0

Merci pour ce Dimitre. Je vais l'essayer sous peu. – Andez

+0

+1 Très bonne réponse. –

+0

désolé la charge de travail vient de passer à travers le toit, donc j'ai dû mettre cela sur le brûleur arrière. Je commence juste à regarder cela maintenant – Andez