Janine S.: XSL Schleife

Hallo allerseits,

da mir hier schonmal schnell und gut geholfen wurde, hoffe ich diesmal wieder auf eure Unterstützung. Ich habe bei XSL-Schleifen immer wieder einen Knoten im Kopf und komme an der Stelle nicht weiter. Habe dazu meinen Code so vereinfacht, dass er hoffentlich noch verständlich ist.

Folgender XML-Inhalt, der nicht verändert werden soll:

<?xml version="1.0" encoding="UTF-8"?>
<list>
   <title>
      <de>Titel DE</de>
      <en>Titel EN</en>
   </title>
</list>

Was ich ausgeben will (txt-Format bzw. konkreter csv):

Titel DE
Titel EN

In der XSL-Datei, die recht komplex ist, will/kann ich allerdings nicht zwei Codes haben, wie bei:

<xsl:value-of select="list/title/de/text()"/>
<xsl:value-of select="list/title/en/text()"/>

Deswegen dachte ich mir, ich überlege mir was cooles. Klappt nur nicht :(

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output media-type="text/plain" encoding="utf-8" version="2.0" method="text"/>
   <xsl:template match="list">
      <xsl:variable name="lang">
         <lang>de</lang>
         <lang>en</lang>
      </xsl:variable>
      <xsl:for-each select="$lang">
         <xsl:variable name="title" select="title/* [name() = $lang/lang]"/>
         <xsl:value-of select="$title"/>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

Wisst ihr warum?

Grüße, Janine

akzeptierte Antworten

  1. Hallo Janine,

    Wisst ihr warum?

    Der Kontext im xsl:for-each, also unterhalb des $lang-Knotens, passt nicht. Probiere es so:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
       <xsl:output media-type="text/plain" encoding="UTF-8" version="2.0" method="text"/>
    
       <xsl:variable name="lang">
         <lang>de</lang>
         <lang>en</lang>
       </xsl:variable>
    
       <xsl:template match="list">
         <xsl:apply-templates select="title"/>
       </xsl:template>
       
       <xsl:template match="title">
         <xsl:for-each select="*[name() = $lang/lang]">
           <xsl:value-of select="concat(., '&#xA;')"/>
         </xsl:for-each>
       </xsl:template>
    
    </xsl:stylesheet>
    
    

    Ergebnis:
    Titel DE
    Titel EN

    Grüße,
    Thomas

    1. Besten Dank! Hat funktioniert und der Knoten im Kopf ist erstmal wieder weg. Bis zum nächsten Mal ;)

      Grüße, Janine

      PS: Dabei gleich noch eine Nachfrage: Warum schreibt man immer so viele templates und ruft die später auf anstatt gleich den Code im ersten Template zu verwenden? Das bläht doch sonst unnötig auf...

      1. Hallo Janine,

        PS: Dabei gleich noch eine Nachfrage: Warum schreibt man immer so viele templates und ruft die später auf anstatt gleich den Code im ersten Template zu verwenden? Das bläht doch sonst unnötig auf...

        Zur Verarbeitung knapper Strukturen kann man das so halten. Bei komplexeren Aufgaben sind verknüpfte Templates überschaubarer sowie besser wart- und wiederverwendbar. Ein Template ist ja eine funktionale Einheit und in anderen Sprachen würde man auch nur ungern alles in eine function(){} legen.

        Grüße,
        Thomas