Christian Seiler: Ich bin am verzweifeln, meine XSLT Datei tut nicht was sie soll!

Beitrag lesen

Hallo,

Für einen Hinweis auf den möglichen Fehler, der sich voraussichtlich in der XSLT Datei befindet wäre ich sehr dankbar.

Ich kenne mich mit dem Ausgabeformat überhaupt nicht aus, daher kann ich nichts darüber sagen. Allerdings: Du scheinst XSLT noch nicht ganz verstanden zu haben, denn Dein XSL-Code enthält folgendes:

<xsl:template match="kopf">
<xsl:for-each select="kopf">

(Und das gleiche für jedes andere Template.)

Das ist funktional gedacht - Du willst eine Schleife haben (for-each). Dummerweise ist in XSLT for-each keine Schleife im imperativen Sinn. Und XSLT funktioniert auch nicht so, wie eine normale imperative Programmiersprache - XSLT ist nämlich vom Konzept her eher funktional.

Mal ein sehr einfaches Beispiel:

<?xml version="1.0"?>  
<staedte>  
<stadt>Berlin</stadt>  
<stadt>Paris</stadt>  
</staedte>

Und vergleiche folgendes XSLT:

<?xml version="1.0"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
  
<xsl:template match="/">  
  <saetze>  
    <xsl:apply-templates />  
  </saetze>  
</xsl:template>  
  
<xsl:template match="stadt">  
  <satz>  
    <xsl:value-of select="." />  
    <xsl:text> ist eine schöne Stadt.</xsl:text>  
  </satz>  
</xsl:template>  
  
</xsl:stylesheet>

Ausgabe davon ist:

<?xml version="1.0"?>  
<saetze>  
<satz>Berlin ist eine schöne Stadt.</satz>  
<satz>Paris ist eine schöne Stadt.</satz>  
</saetze>

Warum? Nun, weil xsl:apply-templates dem XSLT-Prozessor sagt: Gehe *alle* Kindknoten durch und verarbeite sie. Wie werden die verarbeitet? Entweder indem ein passendes Template gefunden wird (wie hier der Fall ist) oder indem das Default-Template angewendet wird (das laut XSLT-Spezifikation nur ein xsl:apply-templates/ enthält).

Sprich: Du brauchst gar keine Schleife mehr - das erledigt XSLT schon für Dich. Denn in einem Template ist der aktuelle XPath-Knoten (auch "." genannt) eben der Knoten, der vom Template gematcht wurde. Eine Anweisung <xsl:for-each select="stadt"> im stadt-Template würde als dazu führen, dass alle Knoten stadt *innerhalb* des gerade gematchten Knotens stadt gesucht werden - und nachdem nirgendwo <stadt> *innerhalb* von <stadt> vorkommt (oder bei Dir <kopf> *innerhalb* von <kopf>) matcht das select-Attribut vom for-each halt gar nichts und die Ausgabe bleibt leer.

Viele Grüße,
Christian

PS: In Deiner DTD fehlt übrigens noch: <!ELEMENT rabe (kopf, koerper)> Allerdings: Für so ein einfaches Beispiel brauchst Du IMHO keine DTD...