André Laugks: xsl:if

Hallo!

Folgende XMl-Datei ist gegeben. Mit einem XSL-template möchte ich nur das element mit der id 13 auswählen.

// ---------- xml-Datei --------------
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="name.xsl"?>
<adressbuch>
 <eintrag id="1">
  <vorname>Andre</vorname>
  <nachname>Laugks</nachname>
  <email>andre.laugks@netcologne.de</email>
 </eintrag>
 <eintrag id="13">
  <vorname>Thomas</vorname>
  <nachname>Otto</nachname>
  <email>thomas.otto@gmx.de</email>
 </eintrag>
 <eintrag id="7">
  <vorname>Werner</vorname>
  <nachname>Schmitz</nachname>
  <email>werner.schmitz@web.de</email>
 </eintrag>
</adressbuch>

Mit dem folgenden XSL-Template wird mir der Vorname des Eintrages 13 ausgewählt, aber die id des ersten "eintrag" Elementes.

// ---------- XSL-Template --------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/adressbuch">
  <html>
   <body>
    <table border="1">
     xsl:apply-templates/
    </table>
   </body>
  </html>
 </xsl:template>

<xsl:template match="eintrag">
  <xsl:if test="@id = 13">
   <tr>
    <xsl:apply-templates select="vorname"/>
   </tr>
  </xsl:if>
 </xsl:template>

<xsl:template match="vorname">
  <td>
   <xsl:value-of select="."/>
  </td>
  <td>
   <xsl:value-of select="/adressbuch/eintrag/@id"/>
  </td>
 </xsl:template>

</xsl:stylesheet>

// ---------- XSL-Template --------------
<html><body>
      <table border="1">
         <tr>
            <td>Thomas</td>
            <td>1</td>
         </tr>
      </table>
</body></html>

Warum wird mir die id des ersten "eintrag" Elementes ausgewählt. Das Templaterule wird doch nur aufgerufen, wenn die id=13 ist, was man ja am Vornamen sieht.

Schreibe ich aber das Template folgendermaßen um, funktioniert es. Wieso?

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/adressbuch">
  <html>
   <body>
    <table border="1">
     xsl:apply-templates/
    </table>
   </body>
  </html>
 </xsl:template>

<xsl:template match="eintrag">
  <xsl:if test="@id = 13">
   <tr>
    <td><xsl:value-of select="vorname"/></td>
    <td><xsl:value-of select="@id"/></td>
   </tr>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>

// ---------- Ergebnis --------------
<html><body>
      <table border="1">
         <tr>
            <td>Thomas</td>
            <td>13</td>
         </tr>
      </table>
</body></html>

MfG, André Laugks
L-Andre @ gmx.de

  1. <xsl:template match="vorname">
      <td>
       <xsl:value-of select="."/>
      </td>
      <td>
       <xsl:value-of select="/adressbuch/eintrag/@id"/>
      </td>
    </xsl:template>

    Warum wird mir die id des ersten "eintrag" Elementes ausgewählt. Das Templaterule wird doch nur aufgerufen, wenn die id=13 ist, was man ja am Vornamen sieht.

    Das muss schon ../@id heissen, ansonsten verlierst du den Kontext, in dem du dich befindest, sprich, das erste Element wird genommen statt des dem aktuellen übergeordnetem.

    Schreibe ich aber das Template folgendermaßen um, funktioniert es. Wieso?

    Weil du hier nicht durch einen absoluten Pfad den Kontext verlässt.

    1. <xsl:template match="vorname">
        <td>
         <xsl:value-of select="."/>
        </td>
        <td>
         <xsl:value-of select="/adressbuch/eintrag/@id"/>
        </td>

      Hallo!

      Das muss schon ../@id heissen, ansonsten verlierst du den Kontext, in dem du dich befindest, sprich, das erste Element wird genommen statt des dem aktuellen übergeordnetem.

      Da geht ein Licht auf.

      Weil du hier nicht durch einen absoluten Pfad den Kontext verlässt.

      Aaaahhhha! Weil, ich wollte eben noch was schnell dazu schreiben.

      Durch den XPath-Ausdruck /adressbuch/eintrag[@id=13]/@id komme ich zu richtigen "eintrag" Element.

      MfG, André Laugks
      L-Andre @ gmx.de

      1. Hallo Andre,

        <xsl:value-of select="/adressbuch/eintrag/@id"/>
        Das muss schon ../@id heissen,
        Da geht ein Licht auf.

        An sich logisch, oder?
        Mit "/adressbuch/eintrag/@id" gehst du praktisch wieder vom Dokumentroot aus.
        Was du aber hier suchtest ist (in deinem Fall) die ID des Elternelements, also parent::node()/@id was man mit ../@id abkürzen kann.

        Aaaahhhha! Weil, ich wollte eben noch was schnell dazu schreiben.

        Durch den XPath-Ausdruck /adressbuch/eintrag[@id=13]/@id komme ich zu richtigen "eintrag" Element.

        Auch logsich ;-) weil du hier im und mit dem Prädikat [@id=13] bereits eine Selektion vornimmst. D.h. du bestimmst, dass nur dann die ID selektiert werden soll, wenn sie 13 ist.
        Dieser Ausdruck ist zwar richtig, aber auch ziemlich redudant.

        Grüße
        Thomas

        1. Hallo!

          Mit "/adressbuch/eintrag/@id" gehst du praktisch wieder vom Dokumentroot aus.
          Was du aber hier suchtest ist (in deinem Fall) die ID des Elternelements, also parent::node()/@id was man mit ../@id abkürzen kann.

          Man kann ja absolute und relative Pfade angeben. Ich habe aber nicht wo weit gedacht, daß man ja relative Pfade wie bei der Verlinkung von HTML-Dateien angeben kann, also das ich sozusagen ein Element höher wandern kann und mir dort das Attribut hole (../@id).

          Dieser Ausdruck ist zwar richtig, aber auch ziemlich redudant.

          Da noch mal /adressbuch/eintrag[@id=13]/@id anzugeben fand ich auch zuviel.

          MfG, André Laugks
          L-Andre @ gmx.de