Question

En ce qui concerne la version XSLT Umbraco 1.

Je aprox. 150 articles de nouvelles en XML. Disons comme ça (tout est pseudocode jusqu'à ce que je connaissent mieux ce xml / xslt):

<news>
  <data alias=date>2008-10-20</data>
</news>
<news>
  <data alias=date>2009-11-25</data>
</news><news>
  <data alias=date>2009-11-20</data>
</news> etc. etc....

Je voudrais courir à travers le XML et créer html-sortie comme une archive de nouvelles. Quelque chose comme (tags pas important):

2008
  Jan
  Feb
  ...
2009
  Jan
  Feb
  Mar
  etc. etc.

Je ne peux pas venir avec un imbriquée for-each (pseudo-code):

var year_counter = 2002
var month_counter = 1
<xsl:for-each select="./data [@alias = 'date']=year_counter">
  <xsl:for-each select="./data [@alias = 'date']=month_counter">
    <xsl:value-of select="data [@alias = 'date']>
  "...if month_counter==12 end, else month_counter++ ..."
  </xsl:for-each>
"... year_counter ++ ..."
</xsl:for-each>

Mais un Pointet programmeur que boucle à travers 10 ans donnera 120 boucles et ce qui est mauvais codage. Depuis que je pense que Umbraco met en cache le résultat que je ne suis pas tellement préoccupé, plus dans ce cas il y aura un max. de 150 documents.

Les indices sur la façon de trier et de sortie de nombreux articles de presse et de les regrouper dans l'année et le groupe chaque année en mois?

Br. Anders

Était-ce utile?

La solution

Pour la solution suivante j'ai utilisé ce fichier XML:

<root>
  <news>
    <data alias="date">2008-10-20</data>
  </news>
  <news>
    <data alias="date">2009-11-25</data>
  </news>
  <news>
    <data alias="date">2009-11-20</data>
  </news>
  <news>
    <data alias="date">2009-03-20</data>
  </news>
  <news>
    <data alias="date">2008-01-20</data>
  </news>
</root>

et cette transformation XSLT 1.0:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:cfg="http://tempuri.org/config"
  exclude-result-prefixes="cfg"
>
  <xsl:output method="xml" encoding="utf-8" />

  <!-- index news by their "yyyy" value (first 4 chars) -->
  <xsl:key 
    name="kNewsByY"  
    match="news" 
    use="substring(data[@alias='date'], 1, 4)" 
  />
  <!-- index news by their "yyyy-mm" value (first 7 chars) -->
  <xsl:key 
    name="kNewsByYM" 
    match="news" 
    use="substring(data[@alias='date'], 1, 7)" 
  />

  <!-- translation table (month number to name) -->
  <config xmlns="http://tempuri.org/config">
    <months>
      <month id="01" name="Jan" />
      <month id="02" name="Feb" />
      <month id="03" name="Mar" />
      <month id="04" name="Apr" />
      <month id="05" name="May" />
      <month id="06" name="Jun" />
      <month id="07" name="Jul" />
      <month id="08" name="Aug" />
      <month id="09" name="Sep" />
      <month id="10" name="Oct" />
      <month id="11" name="Nov" />
      <month id="12" name="Dec" />
    </months>
  </config>

  <xsl:template match="root">
    <xsl:copy>
      <!-- group news by "yyyy" -->
      <xsl:apply-templates mode="year" select="
        news[
          generate-id()
          =
          generate-id(key('kNewsByY', substring(data[@alias='date'], 1, 4))[1])
        ]
      ">
        <xsl:sort select="data[@alias='date']" order="descending" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- year groups will be enclosed in a <year> element -->
  <xsl:template match="news" mode="year">
    <xsl:variable name="y" select="substring(data[@alias='date'], 1, 4)" />
    <year num="{$y}">
      <!-- group this year's news by "yyyy-mm" -->
      <xsl:apply-templates mode="month" select="
        key('kNewsByY', $y)[
          generate-id() 
          =
          generate-id(key('kNewsByYM', substring(data[@alias='date'], 1, 7))[1])
        ]
      ">
        <xsl:sort select="data[@alias='date']" order="descending" />
      </xsl:apply-templates>
    </year>
  </xsl:template>

  <!-- month groups will be enclosed in a <month> element -->
  <xsl:template match="news" mode="month">
    <xsl:variable name="ym" select="substring(data[@alias='date'], 1, 7)" />
    <xsl:variable name="m" select="substring-after($ym, '-')" />
    <!-- select the label of the current month from the config -->
    <xsl:variable name="label" select="document('')/*/cfg:config/cfg:months/cfg:month[@id = $m]/@name" />
    <month num="{$m}" label="{$label}">
      <!-- process news of the current "yyyy-mm" group -->
      <xsl:apply-templates select="key('kNewsByYM', $ym)">
        <xsl:sort select="data[@alias='date']" order="descending" />
      </xsl:apply-templates>
    </month>
  </xsl:template>

  <!-- for the sake of this example, news elements will just be copied -->
  <xsl:template match="news">
    <xsl:copy-of select="." />
  </xsl:template>
</xsl:stylesheet>

Lorsque la transformation est appliquée, la sortie suivante est produite:

<root>
  <year num="2009">
    <month num="11" label="Nov">
      <news>
        <data alias="date">2009-11-25</data>
      </news>
      <news>
        <data alias="date">2009-11-20</data>
      </news>
    </month>
    <month num="03" label="Mar">
      <news>
        <data alias="date">2009-03-20</data>
      </news>
    </month>
  </year>
  <year num="2008">
    <month num="10" label="Oct">
      <news>
        <data alias="date">2008-10-20</data>
      </news>
    </month>
    <month num="01" label="Jan">
      <news>
        <data alias="date">2008-01-20</data>
      </news>
    </month>
  </year>
</root>

Il a la bonne structure déjà, vous pouvez adapter l'apparence réelle à vos propres besoins.

La solution est une approche de regroupement Muenchian deux phases. Dans la première phase, les éléments d'information sont regroupés par année, dans la deuxième phase par année mois.

S'il vous plaît se référer à mon explication de <xsl:key> et key() ici . Vous ne faites pas besoin pour lire l'autre question, mais il est un problème similaire. Il suffit de lire la partie inférieure de ma réponse.

Autres conseils

en plus de Lucero, consultez groupe xsl problème doublons pour éviter les problèmes avec les noms de mois étant enlève

Vous ne pouvez pas faire month_counter ++ dans XSLT, ce n'est pas un langage procédural et ce n'est pas comment fonctionne XSLT. Ainsi, il est inutile de genre à se soucier de ce qui est inefficace si cela ne fonctionne pas de cette façon.

Cela ressemble à une grande douleur dans le cou en XSLT. Mon XSLT n'est pas assez frais pour essayer de mettre en œuvre réellement. Mais voici deux façons:

1)

  • utiliser xsl: clé pour extraire toutes les années uniques -
  • itérer puis à travers ces années. Pour chaque année faire
  • utiliser xsl: clé pour extraire tous les mois
  • Pour chaque mois faire

2) (semble plus facile, si cela fonctionne.)

  • les trier par date, sauf dans la variable tableau trié
  • itérer cette variable (il est important que variable contient le tableau trié)
  • chaque regard de temps preceding-sibling. Si son année / mois ne correspond pas à l'élément courant, écrire l'en-tête approprié

3) Oubliez XSLT, utilisez un vrai langage de programmation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top