2010-03-08 6 views
2

Je rencontre des problèmes pour trouver un moyen de regrouper les éléments xslt 1.0. J'ai un xml source similaire à celui ci-dessous:Regroupement tous les 3 éléments dans xslt 1.0

<client name="client A"> 
    <project name = "project A1"/> 
    <project name = "project A2"/> 
    <project name = "project A3"/> 
    <project name = "project A4"/> 
</client> 
<client name="client B"> 
    <project name = "project B1"/> 
    <project name = "project B2"/> 
</client> 
<client name="client C"> 
    <project name = "project C1"/> 
    <project name = "project C2"/> 
    <project name = "project C3"/> 
</client> 

J'aimerais sélectionner tous les projets, les trier, puis groupe chaque projet 3 dans un boundle comme dans l'exemple ci-dessous:

<boundle> 
    <project name="project A1"> 
    <project name="project A2"> 
    <project name="project A3"> 
</boundle> 
<boundle> 
    <project name="project A4"> 
    <project name="project B1"> 
    <project name="project B2"> 
</boundle> 
<boundle> 
    <project name="project C1"> 
    <project name="project C2"> 
    <project name="project C3"> 
</boundle> 

Pour le moment, j'utilise pour ouvrir une étiquette de liaison et la fermer plus tard. Pouvez-vous penser à une meilleure solution?

Répondre

4

Aucun regroupement nécessaire.

<xsl:param name="perGroup" select="3" /> 

<xsl:variable name="allProjects" select="/client/project" /> 

<xsl:template match="/"> 
    <xsl:apply-templates select="$allProjects" mode="counted" /> 
</xsl:template> 

<xsl:template match="project" mode="counted"> 
    <xsl:if test="position() mod $perGroup = 1"> 
    <xsl:variable name="pos" select="position()" /> 
    <boundle> 
     <xsl:copy-of select="$allProjects[ 
     position() &gt;= $pos and position() &lt; ($pos + $perGroup) 
     ]" /> 
    </boundle> 
    </xsl:template> 
</xsl:template> 
+0

J'aime cette solution, car elle évite les répétitions. Je me demande si cela pourrait être plus simple, puisque maintenant vous bouclez tous les projets, et pour chaque troisième projet, copiez les trois derniers projets, au lieu de copier un projet en premier lieu et mettez simplement les limites autour d'eux ... – OregonGhost

+1

Cela ne peut pas être fait beaucoup plus simple. Vous pouvez faire '' en échange, mais en termes de traitement c'est à peu près la même chose . Aussi, la façon dont je l'ai fait, le modèle '' est autonome. En ce qui concerne l'utilisation potentielle d'une clé XSL: puisqu'il n'y a pas de gamme consécutive de projets, 'position() mod x' ne produira pas les résultats désirés. En dehors de cela, ce qui précède est paramétré, une clé XSL devrait être codée en dur. – Tomalak

+0

est vrai. En faisant fonctionner ma solution (maintenant supprimée), elle devient désespérément complexe traitant de différents cas de bord où le 2ème ou le 3ème projet dans un paquet se déplace dans le suivant, ou le suivant plus un des nœuds de client. – Richard

0

je peux recommander le lien suivant http://www.jenitennison.com/xslt/grouping/ qui m'a aidé à comprendre comment divers groupe nombre d'éléments dans certaines catégories en fonction du contenu du document XML.

+1

Vous ne devriez pas donner un lien vers un autre site en guise de réponse, car le site pourrait être périmé dans le futur. Au lieu de cela, cliquez sur le lien "modifier" sur cette réponse et inclure les parties essentielles de la solution de cette page ici. Voir: http://meta.stackexchange.com/q/8259 –

Questions connexes