Biks: xsl:sort Dynamische Sortierung

Hallo liebe SELFHTML-Gemeinde,

ich stelle in einem Browser XML-Daten (Schallplatten-Infos) per XSL tabellarisch dar. Diese Daten will ich wahlweise nach unterschiedlichen Vorgaben sortieren (Label-Name, Katalog-Nummer, Künstlername). Aus einer HTML-Datei schreibe ich in die Variable "sortierung" eine Textfolge für das entsprechende Element ("labels/label/@name", "labels/label/@catno", "artists/artist/name").
Aus Gründen die ihr besser erklären könnt, muss ich einen relativ komplizierten xsl:sort-Ausdruck verwenden, den ich aber einfach nicht funktionsfähig bekomme:

_____mycoll_gallerie.xsl_____

  
<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
<xsl:output method="html" encoding="UTF-8" />  
  
<xsl:param name="auswahl"/>  
<xsl:param name="sortierung"/>  
  
 <xsl:template match="/">  
  <xsl:choose>  
  
   <xsl:when test="$auswahl=''">  
    <xsl:apply-templates select="releases/release" >  
     <xsl:sort select="*[name() = $sortierung]" order="ascending" data-type="text" />  
    </xsl:apply-templates>  
   </xsl:when>  
  
  </xsl:choose>  
 </xsl:template>  

Die XML-Daten sehen beispielsweise so aus:

_____Biks-collection.xml_____

  
<release id="105393" status="Accepted">  
 <artists><artist><name>Noisy Youth</name></artist></artists>  
 <title>Midelicious EP</title>  
 <labels><label catno="ADV03" name="Adrenogroov" /></labels>  
</release>  

Ich hoffe, ihr versteht was ich meine, ansonsten fragt und/oder ladet euch die kompletten Daten runter (siehe URL).

Also, zusammenfassend meine Frage: Wie muss der xsl:sort-Ausdruck richtig formuliert werden?

Viele Grüße!

Biks

  1. Hallo Biks,

    Also, zusammenfassend meine Frage: Wie muss der xsl:sort-Ausdruck richtig formuliert werden?

    Das hängt letztlich von der Datenstruktur ab. Ein bei $sortierung übergebener String wie "labels/label/@name" stellt jedoch keinen qualifizierten Namen dar, welchen die name()-Funktion beim Vergleich erwarten würde. "label" wäre ein solcher Name.

    Grüße,
    Thomas

    1. Hallo Thomas,

      ja, da hast Du natürlich Recht. Ich habe es auch schon anders probiert gehabt:
      <xsl:sort select="labels/label/*[name() = $sortierung]" order="ascending" data-type="text" /> und dann einfach nur "catno" bzw. "name" übergeben gehabt. Aber das klappte auch nicht.

      Ich werde wohl einfach eine when-Auswahl machen und dementsprechende sort-Anweisungen fest vorgeben.

      Interessant wäre natürlich dennoch eine Lösung.

      Vielen Dank soweit und schönes Wochenende!

      Biks

      Hallo Biks,

      Also, zusammenfassend meine Frage: Wie muss der xsl:sort-Ausdruck richtig formuliert werden?

      Das hängt letztlich von der Datenstruktur ab. Ein bei $sortierung übergebener String wie "labels/label/@name" stellt jedoch keinen qualifizierten Namen dar, welchen die name()-Funktion beim Vergleich erwarten würde. "label" wäre ein solcher Name.

      Grüße,
      Thomas

  2. Guten Morgen,

    ich habe mir nun eine funktionierende Lösung überlegt und ausprobiert. Solange man zwischen Eigenschaften innerhalb eines Tags auswählen möchte, funktioniert folgendes Beispiel:

      
    <xsl:apply-templates select="releases/release" >  
       <xsl:sort select="labels/label/@*[name()=$sortierung]" order="ascending" data-type="text" />  
    </xsl:apply-templates>  
    
    

    Wobei "sortierung" entsprechend meiner XML die Werte catno und name annehmen darf:

      
    <release id="105393" status="Accepted">  
     <artists><artist><name>Noisy Youth</name></artist></artists>  
     <title>Midelicious EP</title>  
     <labels><label catno="ADV03" name="Adrenogroov" /></labels>  
    </release>  
    
    

    Komplizierter wird es, wenn die Sortierung beispielsweise nach dem Künstler erfolgen soll. Da bin ich leider nicht um ein weiteres xsl:choose herumgekommen:

      
    <xsl:param name="auswahl"/>  
    <xsl:param name="sortierung"/>  
      
    <xsl:template match="/">  
       <xsl:choose>  
          <xsl:when test="$sortierung='artist'">  
             <xsl:choose>  
      
                <xsl:when test="$auswahl=''">  
                   <xsl:apply-templates select="releases/release" >  
                      <xsl:sort select="artists/artist/name" order="ascending" data-type="text" />  
                   </xsl:apply-templates>  
                </xsl:when>  
      
                <xsl:otherwise>  
                   <xsl:apply-templates select="releases/release[genres/genre[contains($auswahl, .)][1]]">  
               <xsl:sort select="artists/artist/name" order="ascending" data-type="text" />  
            </xsl:apply-templates>  
                </xsl:otherwise>  
      
             </xsl:choose>  
          </xsl:when>  
          <xsl:otherwise>  
             <xsl:choose>  
      
                <xsl:when test="$auswahl=''">  
                   <xsl:apply-templates select="releases/release" >  
                      <xsl:sort select="labels/label/@*[name()=$sortierung]" order="ascending" data-type="text" />  
                   </xsl:apply-templates>  
                </xsl:when>  
      
                <xsl:otherwise>  
                   <xsl:apply-templates select="releases/release[genres/genre[contains($auswahl, .)][1]]">  
                      <xsl:sort select="labels/label/@*[name()=$sortierung]" order="ascending" data-type="text" />  
                   </xsl:apply-templates>  
                </xsl:otherwise>  
      
             </xsl:choose>  
          </xsl:otherwise>  
       </xsl:choose>  
    </xsl:template>  
      
    
    

    Vielleicht hilft das ja mal jemanden weiter.

    Viele Grüße!

    Biks