c300: Daten aus XML extrahieren

Hallo

Ich versuche seit geraumer Zeit eine XSL-Transfomrmation zu finden, die  es mir ermöglicht aus folgender XML-Struktur:

<student>
   <name>peter</name>
   <fach>Deutsch</fach>
   <fach>Englisch</fach>
</student>
<student>
   <name>paul</name>
   <fach>Deutsch</fach>
   <fach>Französisch</fach>
</student>
<student>
   <name>heike</name>
   <fach>Deutsch</fach>
   <fach>Französisch</fach>
</student>

eine Ausgabe der Form:

Deutsch:
peter
paul
heike

Englisch:
peter

Französisch:
paul
heike

erzeugt. Natürlich ist die Ausgabe danach noch zu spezifizieren. Problem ist, es existieren rund 60 verschiedene Fächer und ich möchte nicht für jedes Fach ein separates Template erstellen. Schliesslich sollte es auch ohne anpassungen funktionieren, falls neue Fächer hinzukommen würde.

Könnt Ihr mir da ein paar Tips geben?

Danke und frohe Festtage,
c300

  1. Tach c300,

    Natürlich ist die Ausgabe danach noch zu spezifizieren. Problem ist, es existieren rund 60 verschiedene Fächer und ich möchte nicht für jedes Fach ein separates Template erstellen. Schliesslich sollte es auch ohne anpassungen funktionieren, falls neue Fächer hinzukommen würde.

    Probiere mal diesen Ansatz:

      
    <?xml version="1.0" encoding="ISO-8859-1"?>  
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    <xsl:output method="html" encoding="ISO-8859-1"/>  
      
    <xsl:param name="faecher_liste" select="'Deutsch|Englisch|Französisch|'"/>  
    <xsl:key name="faecher" match="student/fach" use="text()"/>  
      
    <xsl:template match="/">  
      <html>  
      <head>  
        <title>XSLT-Test</title>  
      </head>  
      <body>  
      
      <xsl:call-template name="fach_suche">  
        <xsl:with-param name="faecher_liste" select="$faecher_liste"/>  
      </xsl:call-template>  
      
      </body>  
      </html>  
    </xsl:template>  
      
    <xsl:template name="fach_suche">  
      <xsl:param name="faecher_liste" select="$faecher_liste"/>  
      <xsl:param name="akt_fach" select="substring-before($faecher_liste,'|')"/>  
      <xsl:param name="faecher_rest" select="substring-after($faecher_liste,'|')"/>  
      
      <p><xsl:value-of select="$akt_fach"/>:<br />  
        <xsl:for-each select="key('faecher',$akt_fach)">  
          <xsl:value-of select="../name/text()"/><br />  
        </xsl:for-each>  
      </p>  
      
      <xsl:if test="contains($faecher_rest,'|')">  
        <xsl:call-template name="fach_suche">  
          <xsl:with-param name="faecher_liste" select="$faecher_rest"/>  
        </xsl:call-template>  
      </xsl:if>  
    </xsl:template>  
      
    </xsl:stylesheet>
    

    Der eingangs definierte Parameter "faecher_liste" enthält alle zu berücksichtigenden Fächer mit "|"-Zeichen als Trenner. Diese Zeichenkette könnte auch noch dynamisch generiert werden.

    Man liest sich,
    svg4you

  2. Tach c300,

    Problem ist, es existieren rund 60 verschiedene Fächer und ich möchte nicht für jedes Fach ein separates Template erstellen. Schliesslich sollte es auch ohne anpassungen funktionieren, falls neue Fächer hinzukommen würde.

    Hier noch eine kürzere Variante, bei der keine Vorgabe der Fächer mehr nötig ist:

      
    <?xml version="1.0" encoding="ISO-8859-1"?>  
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    <xsl:output method="html" encoding="ISO-8859-1"/>  
      
    <xsl:key name="faecher" match="fach" use="text()"/>  
      
    <xsl:template match="/">  
      <html>  
      <head>  
        <title>XSLT-Test</title>  
      </head>  
      <body>  
      
      <xsl:for-each select="//fach[not(text()=preceding::fach/text())]">  
        <xsl:variable name="fach" select="text()"/>  
        <p><xsl:value-of select="$fach"/>:<br />  
          <xsl:for-each select="key('faecher',$fach)">  
            <xsl:value-of select="../name/text()"/><br />  
          </xsl:for-each>  
        </p>  
      </xsl:for-each>  
      
      </body>  
      </html>  
    </xsl:template>  
      
    </xsl:stylesheet>
    

    Man liest sich,
    svg4you