Stefan Meier: Hintergrund jeder 2. Zeile andersfarbig

Hallo Forum,

ich transformiere eine XML-Datei via XSLT zu einer Tabelle. Dazu benutze ich xsl:for-each. Der Hintergrund jeder Zeile ist dunkelgrau, ich hätte aber gerne jede 2. Zeile hellgrau. Wie geht sowas ?

Gruss, Stefan.

  1. Hallo Stefan,

    ich transformiere eine XML-Datei via XSLT zu einer Tabelle. Dazu benutze ich xsl:for-each. Der Hintergrund jeder Zeile ist dunkelgrau, ich hätte aber gerne jede 2. Zeile hellgrau. Wie geht sowas ?

    Folgendes Beispiel sollte Deine Frage beantworten.
    Die entscheidende Zeile ist

    <xsl:if test="position() mod 2 = 0">

    Der mod-Operator liefert den Rest einer Division. Also bei Divison durch 2 immer 0, wenn es sich um eine gerade Zahl handelt. So fängst Du jeden zweiten Knoten in einer Knotenmenge ab und färbst dann anders ein.

    Du musst nur noch übertragen auf xsl:for-each statt xsl:apply-templates, aber das schaffst Du schon ;-)

    XML

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <?xml-stylesheet href="../xsl/xsl34.xsl" type="text/xsl"?>
    <literaturliste>
      <eintrag>
        <autor>Peter Müller</autor>
        <titel>Mein erstes XML Buch</titel>
        <verlag>Addison-Wesley</verlag>
        <erscheinungsort>Bonn</erscheinungsort>
        <erscheinungsjahr>2000</erscheinungsjahr>
      </eintrag>
      <eintrag>
        <autor>Charles Goldfarb</autor>
        <titel>XML Handbook</titel>
        <verlag>Prentice Hall</verlag>
        <erscheinungsort>Upper Saddle River, NJ</erscheinungsort>
        <erscheinungsjahr>1999</erscheinungsjahr>
      </eintrag>
      <eintrag>
        <autor>Ingrid Schmidt</autor>
        <titel>SGML und XML</titel>
        <verlag>Springer</verlag>
        <erscheinungsort>Heidelberg</erscheinungsort>
        <erscheinungsjahr>1999</erscheinungsjahr>
      </eintrag>
      <eintrag>
        <autor>Thomas Michel</autor>
        <titel>XML kompakt</titel>
        <verlag>Hanser</verlag>
        <erscheinungsort>München</erscheinungsort>
        <erscheinungsjahr>1999</erscheinungsjahr>
      </eintrag>
      <eintrag>
        <autor>Michael Kay</autor>
        <titel>XSLT</titel>
        <verlag>Wrox</verlag>
        <erscheinungsort>Birmingham</erscheinungsort>
        <erscheinungsjahr>2000</erscheinungsjahr>
      </eintrag>
      <eintrag>
        <autor>Eric M. Burke</autor>
        <titel>Java and XSLT</titel>
        <verlag>O'Reilly</verlag>
        <erscheinungsort>Cambridge</erscheinungsort>
        <erscheinungsjahr>2001</erscheinungsjahr>
      </eintrag>
    </literaturliste>

    XSL

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet
         version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/literaturliste">
        <html>
          <head>
            <title>XML-Literaturverzeichnis</title>
          </head>
          <body>
            <h1>Literaturliste</h1>
            <table border="0" cellspacing="1" cellpadding="3">
              <tr>
                <th>Autor</th>
                <th>Titel</th>
                <th>Verlag</th>
                <th>Erscheinungsort</th>
                <th>Erscheinungsjahr</th>
              </tr>
              <xsl:apply-templates select="eintrag"/>
            </table>
          </body>
        </html>
      </xsl:template>

    <xsl:template match="eintrag">
        <xsl:if test="position() mod 2 = 0">
          <tr bgcolor="gray">
            xsl:apply-templates/
          </tr>
        </xsl:if>
        <xsl:if test="position() mod 2 = 1">
          <tr bgcolor="red">
            xsl:apply-templates/
          </tr>
        </xsl:if>
      </xsl:template>

    <xsl:template match="autor | titel | verlag | erscheinungsort | erscheinungsjahr">
        <td>
          xsl:apply-templates/
        </td>
      </xsl:template>

    </xsl:stylesheet>

    Gruß
    Franz

    Gruss, Stefan.

    1. Hi Franz,

      wäre es so nicht einfacher, und schneller?

      <xsl:template match="eintrag">
        <tr>
          <xsl:attribute name="bgcolor">
            xsl:choose
              <xsl:when test="position() mod 2 = 0">gray</xsl:when>
              xsl:otherwisered</xsl:otherwise>
            </xsl:choose>
          </xsl:attribute>

      <xsl:apply-templates />
        </tr>
      </xsl:template>

      Ausprobiert hab ich es gerade (mangels Zeit) aber nicht, aber sollte doch gehen, denk ich.

      Gruß,
      Martin

      1. Hallo Martin,

        wäre es so nicht einfacher, und schneller?

        <xsl:template match="eintrag">
          <tr>
            <xsl:attribute name="bgcolor">
              xsl:choose
                <xsl:when test="position() mod 2 = 0">gray</xsl:when>
                xsl:otherwisered</xsl:otherwise>
              </xsl:choose>
            </xsl:attribute>

        <xsl:apply-templates />
          </tr>
        </xsl:template>

        Ob's schneller ist? Vermutlich, aber es ist wesentlich eleganter und einfacher im Sinne von weniger Code.
        Übrigens ein gutes Beispiel auch für die Notwendigkeit xsl:attribute zu nutzen. Das macht nämlich nur dann Sinn, wenn es von einer Bedingung abhängig ist, dass das Attribut gesetzt wird oder welchen Wert es erhält. Ansonsten sind Attribute Value Templates der einfachere Weg.

        Gruß
        Franz

        1. Hi Franz,

          Ob's schneller ist? Vermutlich, aber es ist wesentlich eleganter und einfacher im Sinne von weniger Code.

          Naja, ich dachte mehr an Elegeanz im Sinne von Wartbarkeit :-) Wenn man mal nicht mehr bgcolor setzen will, sondern ne andere Farbe, muss man nur ein Wort austauschen.

          Ansonsten sind Attribute Value Templates der einfachere Weg.

          Da bin ich emotionslos ;-) Attribute habe ich bisher selten transformieren müssen. Meist mache ich ja BMEcat, der hat nicht sooo viele Attribute.

          Gruß,
          Martin

          1. Hallo Martin,

            Naja, ich dachte mehr an Elegeanz im Sinne von Wartbarkeit :-) Wenn man mal nicht mehr bgcolor setzen will, sondern ne andere Farbe, muss man nur ein Wort austauschen.

            Sag ich doch, weniger Code ;-)

            Gruß
            Franz