Home
Über mich
Veröffentlichungen

XML XML-Schema XPath XSL-T XSL-FO XQuery XProc SVG

XSL-T / Die XSLT - Struktur / xsl:apply-templates, xsl:next-match

xsl:apply-templates, xsl:next-match

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 in XSLT 1.0


<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

xsl:apply-templates in XSLT 2.0 und 3.0


<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.

Arbeiten mit xsl:next-match

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.






Vielen Dank für Ihr Interesse an meiner Arbeit.



V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/XSL_apply_templates.html