2010-01-29 8 views
4

J'ai besoin d'une boucle jusqu'à un nœud spécifique position() et la somme de ces nœuds. Par exemple:Comment faire la somme des valeurs de plusieurs nœuds dans XSLT

  • si ma position est 2 Noeud puis [1] + noeud [2]
  • si ma position est 5 alors noeud [1] + noeud [2] + noeud [3] + noeud [ 4] + nœud [5]

Comment cela peut-il être fait dans XSLT?

ont suit xml

<?xml-stylesheet type="text/xsl" href="sum.xsl"?><root><FIDetail Node1="5" Node2="2" Node3="9" Node4="5" Node5="1" Node6="6" Node7="5" Node8="5" Node9="12" Node10="6" Node11="4" Node12="8" Node13="4" Node14="6" Node15="5" Node16="6" Node17="2" Node18="7" Node19="4" Node20="5" Node21="4" Node22="6" Node23="4" Node24="11" Node25="5" Node26="1" Node27="7" Node28="1" Node29="4" Node30="2" Node31="5" Node32="2" Node33="6" Node34="4" Node35="7" Node36="7" Node37="9" Node38="10" Node39="3" Node40="8" Node41="8" Node42="5" Node43="5" Node44="2" Node45="5" Node46="12" Node47="9" Node48="14" Node49="18" Node50="1"/></root> 

je suis en train de montrer la sortie comme ci-dessous

5 somme de Node1

7 somme de Node1 + Node2

16 somme de Node1 + Node2 + Node3

.... somme de Node1 + ... + Node50

une s'il vous plaît aidez-moi que ce sera XSL

ne fonctionne pas xsl est comme ci-dessous

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:for-each select="//FIDetail/@*"> 
     <br/> 
     <xsl:value-of select="sum(preceding-sibling::*) + ."/> 
     = 
     <xsl:for-each select="preceding-sibling::*"> 
      <xsl:value-of select="name()"/> + 
     </xsl:for-each> 
     <xsl:value-of select="name()"/> 
    </xsl:for-each> 

</xsl:template> 

+0

Marc Gravell, Merci de son travail, vous êtes tellement bien, j'apprécie votre réponse rapide – Kedar

Répondre

1

Vous pourriez être en mesure de concocter une solution qui semble fonctionner, mais il y a un problème inhérent, et votre solution va se briser.

Le problème est que les attributs dans XML n'ont pas d'ordre significatif. Vous ne pouvez pas compter sur les attributs présentés à un processus, dans XSLT ou hors de celui-ci, dans le même ordre que dans le texte. Franchement, je suis surpris que XSLT vous permette même d'utiliser position() dans un attribut prédicat.

(Soit dit en passant, c'est la raison pour laquelle l'identité de transformation utilise ce modèle étrange select="node()|@*". Le @* est nécessaire parce que node() ne correspond pas à des attributs. node() ne correspond pas à des attributs, car les attributs ne sont pas des noeuds. Les nœuds ont la position, et les attributs ne le font pas.

Si votre application dépend de l'ordre des attributs, elle est cassée et vous devez la redessiner.

Il y a un moyen de sortir, cependant, si vous pouvez compter sur les attributs de noms pour fournir une sorte de commande, comme indiqué dans votre exemple:

<xsl:variable name="atts" select="@*"/> 
<xsl:for-each select="$atts"> 
    <xsl:sort select="substring-after(name(), 'Node')" data-type="number"/> 
    <td> 
    <xsl:variable name="this" select="number(substring-after(name(), 'Node'))"/> 
    <xsl:value-of select="sum($atts[ 
        number(substring-after(name(), 'Node')) &lt;= $this])"/> 
    </td> 
</xsl:for-each> 

Est-ce laid? Tu paries. Et ça casse si jamais vous changez votre schéma de nommage d'attribut. Mais ça va fonctionner mais les attributs sont commandés.

+0

Merci Robert Rossney, Celui-ci est également important pour moi. – Kedar

3

La requête XPath pour la somme du nœud de contexte et des frères et sœurs précédents est . + sum(./preceding-sibling::*).

E.g. si vous avez le code XML suivant ...

<a> 
    <b id="a">1</b> 
    <b id="b">2</b> 
    <b id="c">3</b> 
    <b id="d">4</b> 
    <b id="e">5</b> 
    <b id="f">6</b> 
</a> 

... vous pouvez obtenir la somme du nœud avec id = « c » et les noeuds précédents en utilisant l'expression

/a/b[@id="c"]/(. + sum(./preceding-sibling::*)) 
+0

+1. Je pense que somme (. | -prà © sidentiel-sibling :: *) 'est plus à © là © gante. – Tomalak

+0

Vous savez, vous devriez éditer votre question et l'ajouter :) –

+1

@Kedar: Il n'était pas clair dans votre question initiale que vous parliez d'attributs. Ce que vous essayez de réaliser n'est pas possible sans peut-être s'appuyer sur les détails d'implémentation d'un transformateur XSL spécifique. La spécification XML indique que l'ordre des attributs n'est pas pertinent (chapitre 3.1) et que le comportement de la fonction XPath position() n'est pas spécifié pour les noeuds d'attribut. – jarnbjo

2

Pas assez, mais cela fonctionne:

<table> 
    <xsl:for-each select="@*"> 
    <tr> 
     <xsl:variable name="pos" select="position()"/> 
     <xsl:variable name="earlier" select="../@*[position() &lt; $pos]"/> 
     <td> 
     <xsl:value-of select="sum($earlier) + ."/> 
     </td> 
     <td> 
     <xsl:for-each select="$earlier"> 
      <xsl:value-of select="name()"/> + 
     </xsl:for-each> 
     <xsl:value-of select="name()"/> 
     </td> 
    </tr> 
    </xsl:for-each> 
</table> 
+0

Merci à son fonctionnement, j'apprécie votre réponse rapide. – Kedar

Questions connexes