Elenco con xslt

Sto cercando di costruire una lista che analizza tutta la mia documento xml. Ho bisogno di elencare i nomi numerici quindi l’alfa nomi. La lista dovrebbe apparire qualcosa di simile a questo.

6
6600 Training
6500 Training

A
Accelerated Training

T
Training

Questo è un frammento di xml.

<courses>
    <course>         
        <name>Accelerated Training</name>
    </course>
    <course>        
        <name>6600 Training</name>
    </course>   
         <course>        
        <name>Training</name>
    </course>
    <course>        
        <name>6500 Training</name>
    </course>   

</courses>   

Questo è il codice che sto usando attualmente. Ho trovato questo in un’altra domanda sul sito e hanno personalizzato un po’. Attualmente non prendere in considerazione le mie necessità per l’analisi in base al numero e restituisce anche fuori ordine alfabetico.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

  <xsl:output omit-xml-declaration="yes" indent="yes"/> 
  <xsl:variable name="vLower" select= "'abcdefghijklmnopqrstuvwxyz'"/> 
  <xsl:variable name="vUpper" select= "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 

  <xsl:key name="kTitleBy1stLetter" match="courses/course"  use="substring(name,1,1)"/>    

  <xsl:template match="/*">      

    <xsl:for-each select="course [generate-id() = generate-id(key('kTitleBy1stLetter', substring(name,1,1)) [1] ) ]">        
      <xsl:variable name="v1st" select="substring(name,1,1)"/>        
      <h2><xsl:value-of select="$v1st"/></h2>        
      <div class="{translate($v1st, $vUpper, $vLower)}-content">
        <ul>
          <xsl:for-each select="key('kTitleBy1stLetter',$v1st)">               
            <li><xsl:value-of select="name"/></li>
          </xsl:for-each>          
        </ul>      
      </div>      
    </xsl:for-each>        
  </xsl:template>
</xsl:stylesheet>
InformationsquelleAutor BillZ | 2009-04-09



3 Replies
  1. 7

    Fondamentalmente, è necessario di gruppo per la prima lettera e l’ordinamento <name>. Si sono su una buona strada con la tua Muenchian raggruppamento approccio già.

    Vorrei suggerire un’alternativa un po ‘ più facile per l’occhio:

    <xsl:key name="kInitial" match="course" use="substring(name, 1, 1)" />
    
    <xsl:template match="courses">
      <xsl:apply-templates select="course" mode="initial">
        <xsl:sort select="name" />
      </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="course" mode="initial">
      <xsl:variable name="initial" select="substring(name, 1, 1)" />
      <xsl:variable name="courses" select="key('kInitial', $initial)" />
      <xsl:if test="generate-id() = generate-id($courses[1])">
        <h2><xsl:value-of select="$initial"/></h2>
        <ul>
          <xsl:apply-templates select="$courses">
            <xsl:sort select="name" />
          </xsl:apply-templates>
        </ul>
      </xsl:if>
    </xsl:template>
    
    <xsl:template match="course">
      <li>
        <xsl:value-of select="name"/>
      </li>
    </xsl:template>

    uscite:

    <h2>6</h2>
    <ul>
      <li>6500 Training</li>
      <li>6600 Training</li>
    </ul>
    <h2>A</h2>
    <ul>
      <li>Accelerated Training</li>
    </ul>
    <h2>T</h2>
    <ul>
      <li>Training</li>
    </ul>

    EDIT: Per motivi di leggibilità che ho lasciato fuori la parte superiore corpo della prima lettera. La chiave corretta sarebbe questa (non è possibile utilizzare una variabile in una chiave, quindi letterale alfabeto stringhe):

    <xsl:key name="kInitial" match="course" use="
      translate(
        substring(name, 1, 1), 
        'abcdefghijklmnopqrstuvwxyz', 
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      )
    " />

    Lo stesso vale, naturalmente, per il $initial variabile a seconda del modello, ma qui è infatti possibile utilizzare le variabili di nuovo.

    EDIT #2: Dal momento che l’ordinamento è case-sensitive, è possibile utilizzare la stessa espressione:

    <xsl:sort select="translate(substring(name, 1, 1), $vLower, $vUpper)" />
    • Vi ringrazio molto. Per quanto l’analisi è interessato questo è perfettamente funzionante. Tutto questo in una tabella e ho utilizzato il codice qui sotto per creare un effetto di posterizzazione. Come posso implementare questo? <xsl:if test=”position() mod 2 =1)”> <xsl:attribute name=”bgcolor”>#e7e7e7</xsl:attribute> </xsl:if>
    • Dove dovrebbero andare da colorare?
    • +1 per un perspicace, responsabile e non sciatta risposta 🙂
    • Si tratta di una fascia in tabella e la colorazione va in ogni riga.
    • Ma attualmente non è una tabella, ma <h2>, <ul> e <li>. Quindi… dove dovrebbero colorare andare?
    • Mi dispiace quello che ho postato qui è una versione semplificata del mio codice. Ho fatto capire però. Ho bisogno di spostare questo chenck di codice appena sopra il display con il cellulare. <xsl:if test=”(posizione() mod 2 = 1)”> <xsl:attribute name=”bgcolor”>#e7e7e7</xsl:attribute> </xsl:if>
    • Ben fatto. 🙂 Quindi tutto è bene ora?
    • Fantastico script, proprio quello che stavo cercando!

  2. 2

    Un XSLT 2.0 soluzione:

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
        <xsl:template match="/*">
          <xsl:for-each-group select="course"
               group-by="upper-case(substring(name,1,1))">
            <xsl:sort select="current-grouping-key()"/>
    
            <xsl:sequence select=
               "concat('&#xA;', current-grouping-key())"/>
    
            <xsl:for-each select="current-group()">
              <xsl:sort select="upper-case(name)"/>
              <xsl:sequence select="concat('&#xA;&#x9;', name)"/>
            </xsl:for-each>
          </xsl:for-each-group>
        </xsl:template>
    </xsl:stylesheet>

    Quando la trasformazione è applicato sulla originariamente fornito di documento XML:

    <courses>
        <course>
            <name>Accelerated Training</name>
        </course>
        <course>
            <name>6600 Training</name>
        </course>
        <course>
            <name>Training</name>
        </course>
        <course>
            <name>6500 Training</name>
        </course>
    </courses>

    il risultato voluto è prodotto (in formato testo per semplicità produrre il codice Html è lasciato come esercizio per il lettore 🙂

    6 
        6500 Training 
        6600 Training 
    A 
        Accelerated Training 
    T 
        Training

    Nota:

    1. L’uso del <xsl:for-each-gruppo> XSLT 2.0 istruzione

    2. L’uso del corrente-raggruppamento-chiave() e attuale gruppo() XSLT 2.0 funzioni.

    3. L’uso del maiuscole() XPath 2.0 funzione

    • Bella e pulita. +1 Alcune 2.0 funzioni devono essere stati 1.0 dall’inizio. In particolare l’elaborazione di stringhe e di raggruppamento è un dolore 1.0.
  3. 0

    Bene i numeri di parte è difficile, se si desidera qualcosa di complesso, ma in base alla vostra uscita ideale tutti ti manca è un semplice sorta sul tuo per ogni:

    <xsl:sort select="key('kTitleBy1stLetter', substring(name,1,1))" />

    avvertimento: io non sono affermazioni di questo di essere il migliore o solo o altro metodo, solo che questo funziona con arresto completo, e utilizza quello che hai già.

    • Oh, penso che sarebbe <xsl:sort select=”substring(nome, 1, 1)” /> o <xsl:sort select=”nome” />.

Lascia un commento