2010-07-19 17 views
5

Necesito repetir el alfabeto a-z, y para cada uno, imprimir la letra, y luego colocar un código que ya tengo trabajando para mostrar todos los elementos en mi base de datos que comienzan con esa letra. Actualmente, estoy usando un seleccionar para recuperar la primera letra de todos los nombres de elementos que exhibo. Sin embargo, el requisito es mostrar todas las letras, y luego mostrar 'no hay elementos para mostrar' donde no hay elementos. Por lo tanto, ya no puedo usar mi selección, que solo devuelve las letras que tienen elementos.xsl iterar por la lista del alfabeto

¿Cómo puedo hacer esto, sin tener que codificar de forma rígida cada letra, y luego llamar a mi plantilla 26 veces después de cada una?

+2

Buena pregunta (+1). Ver mi respuesta para una solución XSLT 1.0. –

Respuesta

5

Esta transformación:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" > 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:key name="kItemBy1stLetter" match="item" 
    use="substring(.,1,1)"/> 

<xsl:variable name="vDoc" select="/"/> 

<xsl:variable name="vAlphabet" select= 
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" 
/> 

<my:message>No items found.</my:message> 

<xsl:variable name="vMessage" select="document('')/*/my:message"/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "(document('')//node()|document('')//@*|document('')//namespace::*) 
          [ not(position() > 26)] 
    "> 

    <xsl:variable name="vcurLetter" select= 
     "substring($vAlphabet, position(), 1)"/> 
    <xsl:for-each select="$vDoc"> 
     <xsl:variable name="vSearchResult" select= 
     "key('kItemBy1stLetter', $vcurLetter)"/> 

     <xsl:value-of select="concat('&#xA;',$vcurLetter, ': &#xA;')"/> 

     <xsl:copy-of select="$vSearchResult | $vMessage[not($vSearchResult)]/text()"/> 
     </xsl:for-each> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en este documento XML (que juega el papel de "base de datos"):

<database> 
<item>Bicycles</item> 
<item>Computers</item> 
<item>Cars</item> 
<item>Forks</item> 
<item>Gellato</item> 
<item>Hypervehicles</item> 
<item>Ichtiosaurs</item> 
<item>Jobs</item> 
<item>Knots</item> 
<item>Lens</item> 
<item>Miracles</item> 
<item>Notes</item> 
</database> 

produce el resultado deseado:

A: 
No items found. 

B: 
<item>Bicycles</item> 

C: 
<item>Computers</item> 
<item>Cars</item> 

D: 
No items found. 

E: 
No items found. 

F: 
<item>Forks</item> 

G: 
<item>Gellato</item> 

H: 
<item>Hypervehicles</item> 

I: 
<item>Ichtiosaurs</item> 

J: 
<item>Jobs</item> 

K: 
<item>Knots</item> 

L: 
<item>Lens</item> 

M: 
<item>Miracles</item> 

N: 
<item>Notes</item> 

O: 
No items found. 

P: 
No items found. 

Q: 
No items found. 

R: 
No items found. 

S: 
No items found. 

T: 
No items found. 

U: 
No items found. 

V: 
No items found. 

W: 
No items found. 

X: 
No items found. 

Y: 
No items found. 

Z: 
No items found. 
+1

¡Buena respuesta! Y +1 para el patrón de iteración fijo "usted-irá al infierno si lo usa". Pero, el alfabeto está ahí. Por lo tanto, creo que es bueno señalar que no hay nada de malo en "llamar a mi plantilla 26 veces después de cada uno" con recursividad. –