Hi,
Ich hätte gerne eine Liste der Anfangsbuchstaben (case-insensitive) eines Attributwertes (als Links für ne interne Navigation).
Das funktioniert auch einigermaßen.
Solange ein Anfangsbuchstabe nur in Kleinschreibung oder nur in Großschreibung vorkommt (A und d in untenstehendem XML-Ausschnitt), wird auch nur 1 Link erzeugt.
Kommen aber beide Schreibweisen vor (B,C,F im XML-Ausschnitt), werden 2 Links erzeugt.
Ich erhalte also statt der erwarteten Liste
A B C D F
leider die Liste
A B B C C D F F
Eigentlich hatte ich gedacht, durch das translate-Zeug die Groß-/Klein-Schreibung eliminiert zu haben.
Ach ja - Umlaute kommen in den Namen nicht vor, also reicht a-z.
Den mode benutze ich, da ich die Elemente an mehreren Stellen in verschiedener Weise ausgeben will (eben einmal als Navigation und einmal mit voller Information [die restlichen Attribute hab ich hier im Beispiel entfernt, da für das Problem irrelevant]).
encoding ist in beiden Dateien iso-8859-1 (daher sind die Umlaute in den Kommentaren kein Problem).
Der Ausschnitt aus der XSL:
<!-- das erste Template, das sorgt nur für den Aufruf mit sortierten Namen -->
<xsl:template match="catters" mode="shortnavi">
<p class="subnavi">
<xsl:apply-templates select="catter" mode="shortnavi">
<xsl:sort select="@names"/>
</xsl:apply-templates >
</p>
</xsl:template>
<!-- das Template mit dem Problem -->
<xsl:template match="catter" mode="shortnavi">
<xsl:variable name="current"><xsl:value-of select="translate(substring(@names,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:variable>
<!-- für das erste Element wird auf jeden Fall ein Link erzeugt (preceding-sibling würde hier fehlschlagen) -->
<xsl:if test="position()=1">
<a href="#label{$current}"><xsl:value-of select="$current"/></a>
</xsl:if>
<!-- für die folgenden Elemente sollte es nur dann ein Link erzeugt werden, wenn sich der 1. Buchstabe vom vorherigen 1. Buchstabe unterscheidet -->
<xsl:if test="position()>1">
<xsl:variable name="previous"><xsl:value-of select="translate(substring(preceding-sibling::catter[1]/@names,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" /></xsl:variable>
<xsl:if test="$previous != $current">
<a href="#label{$current}"><xsl:value-of select="$current"/></a>
</xsl:if>
</xsl:if>
</xsl:template>
Ein Ausschnitt aus der XML:
<catters>
<catter names="A_aaaa" />
<catter names="A_bbbb" />
<catter names="A_cccc" />
<catter names="B_dddd" />
<catter names="B_eeee" />
<catter names="b_ffff" />
<catter names="C_gggg" />
<catter names="C_hhhh" />
<catter names="c_iiii" />
<catter names="d_jjjj" />
<catter names="d_kkkk" />
<catter names="f_llll" />
<catter names="F_mmmm" />
<catter names="f_nnnn" />
</catters>
Wo liegt mein Denkfehler?
cu,
Andreas
MudGuard? Siehe http://www.mud-guard.de/