XML | XML-Schema | XPath | XSL-T | XSL-FO | XQuery | XProc | SVG |
XSL-T / XSLT-Tipps / XSLT-Konvertierung von XML nach HTML / Arbeiten mit xsl:apply-templates
![]() |
![]() |
➪ Alternativ zur Arbeit mit xsl:for-each besteht die Möglichkeit, dasselbe Ergebnis durch separate Templates (xsl:template match) zu erzielen.
In diesem Verfahren wird die Logik in diverse Einzeltemplates aufgesplittet, die sich dann mit xsl:apply-templates bzw. xsl:call-template gegenseitig aufrufen. Wie schon bei xsl:for-each wird auch hier ganz eng am jeweiligen Kontextnode Mensch gearbeitet.
<xsl:template match="/">
<html>
<head>
<title></title>
</head>
<body>
<table border="1" width="100%">
<thead>
<tr>
<th>Nr</th>
<th>Nachname</th>
<th>Vorname</th>
<th>Wohnort</th>
<th>Einkommen</th>
<th>Ausgaben</th>
<th>Flensburger Punkte</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates
select="Orte/Ort/Mensch">
<xsl:sort
select="Gehalt"
data-type="number"
order="descending" />
</xsl:apply-templates>
</tbody>
</table>
</body>
</html>
</xsl:template>
Das soeben beschriebene <xsl:apply-templates select="Orte/Ort/Mensch"> ruft nunmehr das folgende Template Mensch auf, das wiederum andere Templates aufruft.
<xsl:template match="Mensch">
<tr>
<xsl:if test="position() mod 2 = 0">
<xsl:attribute name="bgcolor">lightgrey</xsl:attribute>
</xsl:if>
<td>
<xsl:value-of select="position()" />
</td>
<xsl:apply-templates select="vorname" />
<xsl:apply-templates select="name" />
<xsl:apply-templates select="../name" />
<xsl:apply-templates select="Gehalt" />
<xsl:call-template name="Ausgaben" />
<td align="center">
<xsl:call-template name="listimport">
<xsl:with-param name="plistnr">1</xsl:with-param>
<xsl:with-param name="pkey">
<xsl:value-of select="id" />
</xsl:with-param>
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template match="Mensch"> ruft die Templates für vorname und name auf: dabei wird auch ../name angesprochen, das sich auf den Parentnode Ort bezieht, das ebenfalls einen Childnode name hat.
<xsl:template match="vorname | name">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template match="Mensch"> ruft ebenfalls das Template Gehalt auf, das seinerseits nicht den tatsächlichen Wert des Gehalt-Nodes ausgibt, sondern diesen über format-number formatiert. format-number hat mindestens zwei Parameter: den realen Wert (der zwingend eine Zahl sein muss), ein Pattern, das beschreibt, wie der reale Wert abgebildet werden soll, und drittens einen optionalen Parameter, der sich auf den Namen eines vorher auf oberster Ebene definierten xsl:decimal-format-Elements bezieht. Im xsl:decimal-format-Element werden nähere Anweisungen für die Dezimalschreibweise (Komma statt Punkt) und Tausender-Gruppierung (Punkt statt Komma) festgelegt.
<xsl:template match="Gehalt">
<td align="right">
<xsl:value-of
select="format-number(., '#.###,00 €', 'euro')" />
</td>
</xsl:template>
Zur Unterscheidung der bisherigen direkten "Template match"-Deklarationen folgt hier noch die Definition eines benannten Templates, das auf die interne Struktur des XML-Dokuments Bezug nimmt (was unter dem Aspekt eines leichten Wartbarkeit der Gesamtanwendung kritisch betrachtet werden sollte).
<xsl:template name="Ausgaben">
<td align="right">
<xsl:choose>
<xsl:when test="sum(Kauf/Gesamt) > Gehalt">
<xsl:attribute name="bgcolor">red</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="bgcolor">yellow</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of
select="format-number(
sum(Kauf/Gesamt),
'#.##0,00 €',
'euro')" />
</td>
</xsl:template>
wg / 26. Oktober 2020
Fragen? Anmerkungen? Tipps?
Bitte nehmen Sie Kontakt zu mir auf.
V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn
☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de