XML | XML-Schema | XPath | XSL-T | XSL-FO | XQuery | XProc | SVG |
XSL-T / Die XSLT - Struktur / xsl:apply-templates, xsl:next-match
![]() |
![]() |
➪ Ein alternativer Ansatz zur Arbeit mit xsl:for-each ist xsl:apply-templates.
Auf dieser Seite:Siehe auch
<xsl:apply-templates
select = node-set-expression
mode = qname>
<!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>
<xsl:apply-templates
select? = expression
mode? = token>
<!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>
Siehe auch https://www.w3.org/TR/xslt20/#element-apply-templates.
Siehe auch https://www.w3.org/TR/xslt-30/#element-apply-templates.
Siehe ebenso:
Hier wird eine stufenweise Auslagerung in separate Templates gepflegt, die sich besonders für textintensive Dokumente mit gemischter Strukturierung der Child-Elemente (mixed content) eignet.
Im template match="/" wird der generelle Aufbau des HTML-Zieldokuments definiert; an geeigneter Stelle wird mit xsl:apply-templates select wiederum über XPath ein zweites Template aufgerufen, das für alle Ort-Knoten zuständig ist.
Dieses Prinzip können Sie weiter treiben: Im Template Ort wird das Template name aufgerufen, das nun endlich die formatierte Ausgabe aus dem aktuellen Knoten (.) erzeugt.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h3>Erste Transformation aus XML</h3>
<xsl:apply-templates select="/Orte/Ort"/>
</body>
</html>
</xsl:template>
Erste Auslagerung in ein Template: Es wird bei jedem Ort-Element aufgerufen, das bei <xsl:apply-templates select="/Orte/Ort"/> angesprochen wird. Dieses Template ruft seinerseits wieder template match="name"/> auf.
<xsl:template match="Ort">
<xsl:apply-templates select="name"/>
</xsl:template>
Das Template name wird durch das vorhergehende Template Ort aufgerufen, und es ruft seinerseits ein anderes Template auf, ohne dieses jedoch klar zu bezeichnen.
<xsl:template match="name">
<p>Dieser Ort heisst:
<b><xsl:apply-templates/></b>
</p>
</xsl:template>
Zur Laufzeit stellt sich heraus, dass name einen Textnode als Child-Element hat, der sich durch xsl:template match="text()"/> ansprechen lässt.
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
Der Template-Ansatz bietet die Möglichkeit, dass Sie diverse Templates in externe XSL-Dateien auslagern und diese später über xsl:import bzw. xsl:include einbinden können. Damit können Sie Stylesheets für diverse Ansätze leichter wieder verwenden. Ob sich die Auslagerung und der Re-Import tatsächlich als vorteilhaft erweisen, sei dahin gestellt.
Der Unterschied liegt in der Ranghierarchie der Templates: Während bei xsl:include die eingebundenen Templates denselben Rang haben wie die Templates des inkludierenden Stylesheets, haben importierte Variablen und Templates einen geringeren Rang als jene des importierenden Stylesheets.
xsl:apply-imports entfernt vergleichbar, bietet die Arbeit mit xsl:next-match Zugriff auf eine flexible Verarbeitungslogik. Hier können Sie mehrere Templates definieren, die dieselben Elemente mit unterschiedlichen Prioritäten ansprechen. (Dieser Effekt ist mit xsl:for-each oder xsl:for-each-group nicht erreichbar.)
Das folgende Beispiel soll dies veranschaulichen. xsl:template match="name"/> trifft sämtliche name-Elemente, name[../name()='Mensch'] dagegen nur jene Elemente, deren Parent-Nodes Mensch heißen, und name[../name()='Ort'] jene Elemente, deren Parentnodes Ort heißen. Letztere haben jedoch eine andere Priorität: Durch den Aufruf von xsl:next-match wird xsl:template match="name"/> angesprochen, das jedem generierten Element STADT oder PERSON ein Attribut NAME beifügt.
<xsl:template match="/Orte">
<ROOT>
<xsl:apply-templates
select="descendant::name"/>
</ROOT>
</xsl:template>
<xsl:template
match="name">
<xsl:attribute name="NAME">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template
match="name[../name()='Mensch']">
<PERSON>
<xsl:next-match/>
</PERSON>
</xsl:template>
<xsl:template
match="name[../name()='Ort']">
<STADT>
<xsl:next-match/>
</STADT>
</xsl:template>
Mehr zum Thema: for-each, apply, call
wg / 24. September 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