2010-05-17 5 views
2

Je voudrais avoir une liste triée en ignorant les articles définitifs/indéfinis initiaux 'the' et 'a'. Par exemple:En ignorant 'A' et 'The' lors du tri avec XSLT

  • La Comédie des erreurs
  • Hamlet
  • A Midsummer Night de rêve
  • Douzième Nuit
  • Tale Hiver

Je pense que peut-être dans XSLT 2.0 cela pourrait être réalisé sur le modèle de:

<xsl:template match="/"> 
    <xsl:for-each select="play"/> 
    <xsl:sort select="if (starts-with(title, 'A ')) then substring(title, 2) else 
         if (starts-with(title, 'The ')) then substring(title, 4) else title"/> 
    <p><xsl:value-of select="title"/></p> 
    </xsl:for-each> 
</xsl:template> 

Cependant, je veux utiliser le traitement dans le navigateur, donc je dois utiliser XSLT 1.0. Y a-t-il un moyen d'y parvenir dans XLST 1.0?

+4

En général, la bonne approche pour cela est de stocker un "titre de tri" pour chaque élément, étant donné que les règles peuvent devenir très complexe et même s'étendre dans d'autres langues (par exemple "Die" est un article et devrait être ignoré en allemand, mais "Die Hard" ne devrait pas être trié sous "H", même s'il se trouve dans un index germanophone). Le titre de tri de "A Midsummer Night's Dream" serait "Midsummer Night's Dream, A". –

+0

Je devrais avoir mentionné, starts-with() est disponible en XLST 1.0, mais si-alors-else n'est pas ... – ChrisV

+0

@Joachim - vous avez raison, mais je dois travailler avec des données existantes, il n'y a pas de ressources à maintenir un champ de tri parallèle; La solution rapide-n-sale de Gart est juste ce dont j'ai besoin - bon commentaire, bien que – ChrisV

Répondre

4

Cette transformation:

<xsl:template match="plays"> 
<p>Plays sorted by title: </p> 
    <xsl:for-each select="play"> 
     <xsl:sort select= 
     "concat(@title 
       [not(starts-with(.,'A ') 
        or 
        starts-with(.,'The '))], 
       substring-after(@title[starts-with(., 'The ')], 'The '), 
       substring-after(@title[starts-with(., 'A ')], 'A ') 
      ) 
    "/> 
     <p> 
     <xsl:value-of select="@title"/> 
     </p> 
    </xsl:for-each> 
</xsl:template> 

lorsqu'il est appliqué sur ce document XML:

produit le résultat souhaité, correct:

<p>Plays sorted by title: </p> 
<p>Barber</p> 
<p>The Comedy of Errors</p> 
<p>CTA &amp; Fred</p> 
<p>Hamlet</p> 
<p>A Midsummer Night's Dream</p> 
<p>Twelfth Night</p> 
<p>The Winter's Tale</p> 
+0

Une deuxième excellente solution, Dimitre, qui évite les calculs de la solution de Gart - merci aussi! Puisque je devais y penser un peu plus, je vais ajouter pour le bénéfice des autres: pour 'The Winter's Tale', par exemple, la valeur sur laquelle il triera sera 'Winter's TaleThe Winter's Tale'. – ChrisV

+0

@ChrisV: Oui, l'avantage de cette solution est qu'elle est plus simple et présente moins de risques de commettre des erreurs dans l'arithmétique. Peu importe que les clés de tri semblent étranges, cela n'affecte pas les valeurs qui sont finalement sorties. –

+0

Il peut y avoir des problèmes si "Le" est le milieu du texte, plus comme "... Quelque chose le quelque chose .." (désolé, ne peut pas penser à un exemple réel). De même, en général, l'article "An" doit également être traité en conséquence. – Gart

2

Voici comment je le ferais:

<xsl:template match="plays"> 
    <xsl:for-each select="play"> 
     <xsl:sort select="substring(title, 1 + 2*starts-with(title, 'A ') + 4*starts-with(title, 'The '))"/> 
     <p> 
     <xsl:value-of select="title"/> 
     </p> 
    </xsl:for-each> 
</xsl:template> 

Mise à jour: J'ai oublié d'ajouter 1 à l'expression (classique hors par une erreur)

Eh bien, starts-withest à partir de XSLT 1.0. Prooflink: le premier résultat de recherche dans Google donne XSLT 1.0: function starts-with

+0

Le problème est que 'starts-with' est XSLT 2.0, je pense - * Edit * Je suis corrigé! – Phil

+1

Je me suis corrigé dès que j'ai frappé poste il y a 23 minutes, je ne voulais tout simplement pas supprimer le commentaire original, car il semble suspect de supprimer ses propres erreurs. À votre santé. – Phil

+0

Excellente solution simple et créative Gart - Merci! – ChrisV

Questions connexes