2013-05-16 4 views
0

J'ai la liste suivante d'articles.XSLT grouper les articles par le nombre

<items> 
    <item type="Type1">Item1</item> 
    <item type="Type2">Item2<item> 
    <item type="Type2">Item3<item> 
    <item type="Type3">Item4<item> 
    <item type="Type3">Item5<item> 
    <item type="Type1">Item6<item> 
    <item type="Type3">Item7<item> 
    <item type="Type1">Item8<item> 
    <item type="Type2">Item9<item> 
    <item type="Type1">Item10<item> 
<items> 

Je vais avoir du mal à déterminer le XSLT nécessaire pour que ci-dessus sont affichées en groupes de Type1 (x1), Type2 (x2), Type3 (x4), où les chiffres sont indiqués entre parenthèses le nombre ou Moins. En d'autres termes, le but est de créer un motif répétitif: l'élément suivant de Type1 s'il en reste, puis les deux suivants de Type2 ou moins s'il reste moins de deux, puis les quatre suivants de Type3 ou moins si moins que quatre restent.

donc la sortie désirée ressemblerait à quelque chose comme ci-dessous: A partir de la sortie ci-dessus

<div class="Items"> 
    <div class="Type1">Item1</div> 
    <div class="Type2">Item2</div> 
    <div class="Type2">Item3</div> 
    <div class="Type3">Item4</div> 
    <div class="Type3">Item5</div> 
    <div class="Type3">Item7</div> 
    <div class="Type1">Item6</div> 
    <div class="Type2">Item9</div> 
    <div class="Type1">Item8</div> 
    <div class="Type1">Item10</div> 
</div> 

, vous pouvez voir que l'ordre a changé. c'est-à-dire < = 1 Type 1, suivi de < = 2 Type2, suivi de < = 4 Type3, et ce motif se répète. Je suppose que les éléments devront être groupés dans le modèle décrit et se répéter jusqu'à la liste complète si les éléments sont épuisés. J'espère que j'ai un sens.

Quelqu'un peut-il fournir le XSLT requis ou des pointeurs s'il vous plaît?

Merci, John.

+1

pouvez-vous ajouter un peu plus de contexte, je peux » t voir comment la sortie est ordonnée du tout? Ils ne sont pas groupés ou classés par classe, et il semble que, en dehors de commutation d'articles 6 et 7, et 8 et 9, la sortie est la même. –

+0

Dans la formulation actuelle, ce n'est pas une question réelle - il est difficile de donner un sens aux règles requises (le cas échéant) que la transformation devrait implémenter. S'il vous plaît, éditez et expliquez. –

+0

Salut les gars, j'ai édité le post. Merci d'avoir regardé ça. –

Répondre

0

S'il vous plaît donner ce un tourbillon:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="kType2Group" match="item[@type = 'Type2']" 
      use="floor(count(preceding-sibling::item[@type = 'Type2']) div 2) + 1"/> 
    <xsl:key name="kType3Group" match="item[@type = 'Type3']" 
      use="floor(count(preceding-sibling::item[@type = 'Type3']) div 4) + 1"/> 

    <xsl:template match="@* | node()" name="Copy"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:apply-templates select="item[@type = 'Type1']" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="item[@type = 'Type1']"> 
    <xsl:call-template name="Copy" /> 
    <xsl:apply-templates select="key('kType2Group', position())" /> 
    <xsl:apply-templates select="key('kType3Group', position())" /> 
    </xsl:template> 
</xsl:stylesheet> 

Lorsqu'il est exécuté sur votre XML d'entrée, le résultat est:

<items> 
    <item type="Type1">Item1</item> 
    <item type="Type2">Item2</item> 
    <item type="Type2">Item3</item> 
    <item type="Type3">Item4</item> 
    <item type="Type3">Item5</item> 
    <item type="Type3">Item7</item> 
    <item type="Type1">Item6</item> 
    <item type="Type2">Item9</item> 
    <item type="Type1">Item8</item> 
    <item type="Type1">Item10</item> 
</items> 

Les clés dans ce cas sont utilisées pour séparer les éléments Type2 et Type3 en groupes, afin qu'ils puissent être récupérés par leur numéro de groupe (1, 2, 3, etc.) la logique pour déterminer les numéros de groupe est de compter le nombre d'éléments précédents du même type, diviser ce nombre par le nombre d'éléments dans chaque groupe, arrondissez vers le bas et ajoutez-en un. Ainsi, par exemple, ce calcul effectué pour les quatre premiers types2 serait:

floor(0 div 2) + 1 = floor(0) + 1 = 0 + 1 = 1 
floor(1 div 2) + 1 = floor(0.5) + 1 = 0 + 1 = 1 
floor(2 div 2) + 1 = floor(1) + 1 = 1 + 1 = 2 
floor(3 div 2) + 1 = floor(1.5) + 1 = 1 + 1 = 2 

et ainsi de suite.

La logique générale du XSLT est:

  • le match élément racine, le copier et appliquer des modèles à tous les éléments Type1.
  • Le modèle pour les éléments Type1:
    • Copie l'élément lui-même.
    • utilise la clé pour appliquer des modèles aux éléments Type2 dans son groupe (position() sera 1 pour le premier élément Type1, 2 pour le deuxième, et ainsi de suite.
    • utilise la clé pour appliquer des modèles aux éléments Type3 dans son groupe
  • le premier modèle, le modèle d'identité, fait le travail de copie tout ce qui n'a pas tout autre modèle pour le match.
+0

Merci @JLRishe. Cela a fonctionné quand je l'ai mis à travers http://xslttest.appspot.com/. Comme vous pouvez probablement le dire, je ne suis pas très bon avec XSLT. Ce serait génial si vous pouvez me donner un peu d'une solution à travers votre solution? Surtout autour de l'utilisation des clés. –

+0

Ajout d'un peu d'élaboration ci-dessus. – JLRishe

+0

Génial! C'est un truc puissant. Je vais essayer d'appliquer cela au scénario que j'ai sous la main. Merci encore. –