2009-11-17 5 views
0

J'ai créé un modèle récursif pour obtenir le premier nombre d'éléments de mon XML.xsl nœud de boucle récursif par index

Il utilise un index (compteur) exactement comme je le ferais dans une boucle for. Maintenant, comment puis-je obtenir un noeud de mon XML en utilisant l'index?

J'ai essayé [position() = $ index] mais il avait un comportement bizarre quand j'essayais d'obtenir des nœuds plus profonds dans la hiérarchie XML.

Si je XML tels que:

<0> 
<1> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
</1> 
</0> 

Je veux pouvoir compter à travers et copier les 2 années jusqu'à ce que j'ai autant que je veux.

Répondre

0

J'utiliserais < xsl: pour chaque ... > avec position() au lieu de récursivité.

+0

Toutes mes excuses - a donné aveuglément la même réponse que vous sans y prêter attention. –

0

Je ne vois pas pourquoi vous avez besoin d'un modèle récursif pour cela. Vous pouvez utiliser un < xsl: pour chaque > pour y parvenir. (j'ai changé le nom de l'élément pour la rendre légale) Par exemple:

<xsl:variable name='n' select='10'/> 
<xsl:for-each select='two[position() &lt; $n]'> 
    <!-- do whatever you need to do --> 
</xsl:for-each> 

Vous pouvez utiliser un attribut de sélection que vous voulez et vous pouvez inclure un < xsl: sort > dans le for-each si votre entrée est plus complexe que votre exemple.

+0

Désolé peut-être que j'aurais dû ajouter un autre détail. Ce que je veux vraiment, c'est sortir les éléments en groupes, je veux résumer les groupes avant qu'ils ne soient sortis. Mais j'ai besoin de les regrouper d'abord dans un arbre fragmenté afin que je puisse faire des fonctions sur chaque groupe. C'est ce que fait la boucle que j'ai. Donc, j'ai juste besoin d'obtenir le nœud approprié en fonction de l'index. Ou est-ce pas possible? Je suis un noob. – Ben

+0

Utilisez-vous XSLT version 1 ou 2? XSLT 2.0 rendra cela beaucoup plus facile je pense - il y a des instructions de regroupement dans XSLT 2.0 où vous devez rouler les vôtres dans 1.0 –

1

Vous dites que vous voulez traiter vos éléments dans des groupes de n. La solution XSLT 1.0 suivante, il fait:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:param name="pGroupCount" select="3" /> 

    <xsl:template match="/lvl-0"> 
    <xsl:copy> 
     <!-- select the nodes that start a group --> 
     <xsl:apply-templates mode="group" select=" 
     lvl-1/lvl-2[position() mod $pGroupCount = 1] 
     " /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="lvl-2" mode="group"> 
    <!-- select the nodes belong to the current group --> 
    <xsl:variable name="current-group" select=" 
     . | following-sibling::lvl-2[position() &lt; $pGroupCount] 
    " /> 
    <!-- output the current group, you can also do calculations with it --> 
    <group id="{position()}"> 
     <xsl:copy-of select="$current-group" /> 
    </group> 
    </xsl:template> 
</xsl:stylesheet> 

Lorsqu'il est appliqué à ce document d'entrée:

<lvl-0> 
<lvl-1> 
    <lvl-2>item.0</lvl-2> 
    <lvl-2>item.1</lvl-2> 
    <lvl-2>item.2</lvl-2> 
    <lvl-2>item.3</lvl-2> 
    <lvl-2>item.4</lvl-2> 
    <lvl-2>item.5</lvl-2> 
    <a>foo</a><!-- to prove that position() calculations still work --> 
    <lvl-2>item.6</lvl-2> 
    <lvl-2>item.7</lvl-2> 
    <lvl-2>item.8</lvl-2> 
    <lvl-2>item.9</lvl-2> 
</lvl-1> 
</lvl-0> 

La sortie suivante est générée:

<lvl-0> 
    <group id="1"> 
    <lvl-2>item.0</lvl-2> 
    <lvl-2>item.1</lvl-2> 
    <lvl-2>item.2</lvl-2> 
    </group> 
    <group id="2"> 
    <lvl-2>item.3</lvl-2> 
    <lvl-2>item.4</lvl-2> 
    <lvl-2>item.5</lvl-2> 
    </group> 
    <group id="3"> 
    <lvl-2>item.6</lvl-2> 
    <lvl-2>item.7</lvl-2> 
    <lvl-2>item.8</lvl-2> 
    </group> 
    <group id="4"> 
    <lvl-2>item.9</lvl-2> 
    </group> 
</lvl-0> 

Pour comprendre cela, vous devez savoir comment position() travaux. Lorsqu'il est utilisé comme ceci:

lvl-1/lvl-2[position() mod $pGroupCount = 1] 

il se réfère à la position de lvl-2 noeuds au sein de leur parent respectif (!). Dans ce cas, il n'y a qu'un seul parent, de sorte que item.0 a la position 1 et la position 10. item.9 a

Lorsqu'il est utilisé comme ceci:

following-sibling::lvl-2[position() &lt; $pGroupCount] 

il se réfère à la position relative le long de l'axe following-sibling::. Dans ce contexte, item.1 aurait une position relative de 1 en ce qui concerne item.0. (En gros, cela est la même chose que ci-dessus, qui compte tout le long de la (implicite) axe child::.)

Lorsqu'il est utilisé lui-même, comme ici:

<group id="{position()}"> 

il se réfère à la position de la nœud actuel du lot en cours de traitement.Dans notre cas, le « lot » se compose de noeuds qui commencent un groupe (item.0, item.3, item.6, item.9), il en va de 1 à 4.

Questions connexes