Michael: XSLT - Sortieren und doppelte Einträge unterdrücken

Beitrag lesen

Hallo Thomas,

danke für die Mühe die Du Dir mit mir gibst. Dein Beispiel hat geholfen und ich glaube ich habe es jetzt wirklich kapiert.

Wie du sehen kannst, wird die Angabe der Position sich verändern, weil die Knoten in der Reihenfolge des Sortierkriteriums abgearbeitet werden.
Aber dies gilt eben nur für die Ausgabe, d.h. wenn du mit "position() = 2" immer auf "A" zugreifen möchtest, funktioniert das nicht, weil die Knoten in anderen Reihenfolge abgearbeitet werden und sich dementsprechnd ihre Position  für die Ausgabe ändert.
Du kannst auch sehen, dass bei for-each immer eine bestimmte Knotenmenge selektiert wird und sich dann auch die Sortierung nur auf diese Knotenmenge bezieht.

Soweit ist jetzt alles klar und einleuchtend.

Allerdings habe ich mein Problem (doppelte Einträge aussortieren und im sortierten Ergebnis jedes zweite Element farblich abheben) trotzdem noch nicht lösen können.

Die Schwierigkeit ist, dass die Knotenmenge die ich mit for-each zunächst selektiere mehr Elemente enthält wie schließlich ausgegeben werden. Ich schaffe es nicht, mit for-each "auf einmal" so zu selektieren, dass nur auszugebende Knoten übrig bleiben.
Das was Du als Lösungsvorschlag mal geschrieben hast...
("
<xsl:variable name="this" value="."/>
<xsl:for-each select="not(preceding-sibling::eintrag[. = $this])">
 <xsl:sort />
 <xsl:if test="(position()mod2) != 0" />
 <xsl:value-of select="."/>
")
... kann doch nicht funktionieren.
(Bei der Variable meintest Du statt value schon select? - frage nur sicherheitshalber, nicht dass Du einen XSLT Prozessor verwendest, der sowas unterstützt und es deshalb bei mir scheitert, wenn ich es durch select ersetze.)

Jedenfalls kann ich die Variable doch nur innerhalb einer for-each Schleife verwenden, da sonst alle Knoten (gleichzeitig) in ihr gespeichert würden und ich in der folgenden Bedingung für die for-each Selektion einen der Knoten gegen alle vergleiche.
Ich habe jetzt alle Variationen, die mir zu Deinem Vorschlag einfielen, durchprobiert und finde einfach keine Lösung mit der ich die Knotenmenge so selektieren kann, dass ich nicht nachträglich doppelte Einträge entfernen müsste.

Auch wenn es etwas mehr Quelltext wird paste ich Dir mal einen Auszug aus meinem XML / XSLT um einmal mit einem konkreten Beispiel zu arbeiten:

XML:
<litlist>
 <ul>
  <li>Scriven, Michael (1967): The methodology of evaluation. In: R. Tyler, R. Gagne und M. Scriven: Perspectives of curriculum evaluation. Rand McNally.</li>
  <li>Thimbleby, Harold (2004). User interface design with matrix algebra. In: ACM Transactions on Computer-Human-Interaction (11-2). S. 181-236.</li>
  <li>Hegner, M. (2003). Methoden zur Evaluation von Sowftware. IZ-Arbeitsbericht Nr. 29, Bonn: InformationsZentrum Sozialwissenschaften (ASI).</li>
  <li>Rosson, M. &amp; Carroll, J. (2002). Usability Engineering - Scenario-based development of human-computer interaction. San Francisco(u.a.): Morgan Kaufmann.</li>
  <li>Rosenfeld, L. &amp; Morville, P. (2002). Information Architecture for the World Wide Web: Designing Large Scale Web Sites. Cambridge: O’Reilly &amp; Associates.</li>
  <li>Rosenfeld, L. &amp; Morville, P. (2002). Information Architecture for the World Wide Web: Designing Large Scale Web Sites. Cambridge: O’Reilly &amp; Associates.</li>
 </ul>
</litlist>
.......................
XSLT (in der Version, in der zwar sortiert und aussortiert wird, aber wo eben das farblich hinterlegen jedes zweiten Listenelements nicht klappt)
.......................
<xsl:template match="litlist/ul">
 <ul>
  <xsl:for-each select="./li">
   <xsl:sort />
   <xsl:variable name="aktuellerKnoten" select="." />
   <xsl:if test="not(preceding-sibling::li[. = $aktuellerKnoten])">
    <li>
     <xsl:attribute name="class">
      <xsl:if test="position() mod 2 = 0">xsl:textlitli</xsl:text></xsl:if>
      <xsl:if test="position() mod 2 = 1">xsl:textlitli2</xsl:text></xsl:if>
     </xsl:attribute>
     <xsl:call-template name="ankersetzen"></xsl:call-template>
     <xsl:apply-templates />
    </li>
   </xsl:if>
  </xsl:for-each>
 </ul>
</xsl:template>

Deshalb kann man sehr gut mit  "position() mod 2" gearde ungerade Positionen von Knoten unterscheiden. ;-)

Sorry, aber bei meinem Beispiel zu den Ergebnissen der Modulo-Division habe ich eigentlich nur die Reihenfolge der Ergebnisse gemeint und nicht die Modulo-Division an sich. Was eine Modulo-Division ist war mir schon klar. Aber trotzdem danke für die Mühe.

Ich hoffe das hilft.

Auch wenn ich mein Problem nicht lösen konnte, geholfen hat es trotzdem ungemein.

Tausend Dank und viele Grüße

Michael