xsl:apply-imports

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 6.)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

 

Der Befehl xsl:apply-imports ist von Bedeutung in Zusammenhang mit importierten XSLT-Stylesheetmodulen. Er reaktiviert Templateregeln, die durch patternidentische mit höherer Importpräzedenz, nämlich im importierenden Stylesheetmodul befindliche, überschrieben wurden.

Klassifizierung Instruktion
Funktionsgruppe Template-Regeln und Aufruf
Einführung XSLT 1.0

Position im Stylesheet und erlaubte Inhalte:

xsl:apply-imports zählt zu den Instruktio­nen und tritt daher nur innerhalb von Templateblöcken auf, dabei allerdings nie im Inneren von xsl:for-each oder xsl:for-each-group-Instruktionen.

Seit XSLT 2.0 sind Instruktionen xsl:with-param als Child-Elemente von xsl:apply-imports gestattet. In XSLT 1.0 liegt die Instruktio­n dagegen als leeres Element vor.

Attribute:

Erlaubt sind alle Standardattribute. Die Instruktion besitzt ansonsten keine elementspezifischen Attribute.

Verwendungszweck:

Importiert ein Stylesheetmodul ein weiteres, das Template-Regeln mit identischem match-Pattern (und gleichzeitig identischem Modus) enthält, so wird jeweils die entsprechende Regel des importierten Sty­lesheetmoduls stillgelegt, da sie die niedrigere Präzedenz besitzt. Dieser Mechanismus hat durchaus Vorteile – in das Hauptmodul importierte Dublet­ten von dort bereits definierten Template-Regeln können nicht stören.

Im Gegenzug – und hierin besteht die eigentliche Bedeutung der Anweisung – können Regeln, die bei Bedarf überschrieben werden sollen, in einem »allge­mein anzuwendenden« Stylesheetmodul zusammengefasst werden. Dieses Modul kann durch ein anderes importiert werden (dieses kann, muss aber nicht das Hauptmodul sein), indem allgemeine durch »spezielle« Anweisungen überschrieben werden.

Gegebenenfalls soll die importierte Template-Regel jedoch nicht komplett außer Kraft gesetzt, sondern ergänzend zu jener im Hauptstylesheetmodul vorliegen­den angewendet werden. Für diesen Fall besteht die Möglichkeit, durch xsl:apply-imports aus einer Template-Anweisung des importierenden Moduls zusätzlich die Ausführung einer durch dieses importierten Template-An­weisung anzuordnen.

Hierbei wird jeweils genau die eine Template-Regel mit der nächstniedrigeren Präzedenz und dem gleichen Templatemodus aktiviert, also nie alle in Frage kommenden Regeln – es sei denn, in der aktivierten Regel befindet sich eben­falls ein xsl:apply-imports, das die Kette um eine Stufe weiterführt.

Existiert keine aktivierbare importierte Regel, so stellt dies keinen Fehler dar. In diesem Fall wird eine passende Default-Regel aktiviert. Mit anderen Worten: xsl:apply-imports verhält sich in diesem Fall ebenso wie xsl:apply-temp­lates.

Aktivierte Template-Regeln im gleichen Importzweig:
Auf diesem Wege akti­viert werden können nur Template-Regeln, die sich mit niedrigerer Präzedenz – vom Modul mit der Aktivierung ausgehend – im gleichen Importzweig befin­den. Dies ist der Fall für alle importierten Template-Regeln, sofern die Aktivie­rung vom Hauptmodul des Templates aus erfolgt.

Es ist jedoch nicht immer möglich, eine Template-Regel ausgehend von einem importierten Modul zu aktivieren. Dies gilt dann, wenn die zu aktivierende Regel sich in einem Modul befindet, das nicht direkt oder indirekt durch dasje­nige Modul importiert wird, in dem die Aktivierung erfolgt (sich also in einem anderen Importzweig befindet). Ob die Regel, die so aktiviert werden soll, vom Hauptmodul aus betrachtet eine niedrigere Präzedenz als die aktivierende besitzt, spielt keine Rolle.

Beispiel für mehrere Importzweige

Abbildung: Beispiel für mehrere Importzweige.

Das Hauptmodul importiert zwei Module A und B, Modul B importiert ein Modul C. Es existieren somit zwei Importzweige. Vom Hauptmodul aus kön­nen alle Regeln in A, B und C aktiviert werden, vom Modul B aus solche in Modul C.

Von Modul A und Modul C aus können keine Regeln aktiviert werden, da sich beide am Ende ihres Importzweiges befinden. Speziell können überdies von A aus (anderer Importzweig) weder Regeln in B noch in C aktiviert werden, obwohl zumindest die Regeln von C, ausgehend vom Hauptmodul, eine niedri­gere Importpräzedenz als diejenigen von A besitzen.

Aktuelle Template-Regel bleibt erhalten:
Durch die Aktivierung eines impor­tierten Templates wird die aktuelle Template-Regel (current template rule) nicht geändert – es wird also mit dem gleichen Current Node gearbeitet, der beim Aufruf der aktivierenden Regel gültig war. Der aktuelle Modus (current mode) wird ebenfalls weitergegeben. Ebenso steht der Tunnelparameterstrom weiter zur Verfügung.

Aktivierungsanweisung aus benannter Template-Regel:
Befindet sich eine Aktivierungsanweisung xsl:apply-imports in einem benannten Template, so entspricht die aktuelle Template-Regel derjenigen Regel, aus der heraus die benannte Regel über xsl:call-template aufgerufen wurde. (Anmerkung: Dies liegt daran, dass xsl:call-template die aktuelle Template-Regel nicht verändert.)

Keine Aktivierung importierter benannter Templates:
Die Instruktion xsl:apply-imports bezieht sich jedoch auf den aktuellen Knoten bzw. die aktuelle Templater-Regel, sodass es deshalb nicht möglich ist, aus einem benann­ten Template mittels xsl:apply-imports ein gleichnamig benanntes Template mit niedrigerer Importpräzedenz zu aktivieren. Statt dessen wird eine Temp­late-Regel niedrigerer Importpräzedenz bezogen auf die aktuelle Template-Regel (siehe oben) aktiviert. (Anmerkung: Ein importiertes benanntes Template kann daher überhaupt nur dann aufgerufen werden, wenn kein gleichnamiges Template höherer Importpräzedenz existiert.)

Keine Aktivierung aus xsl:for-each oder xsl:for-each-group:
Damit die Akti­vierung einer importierten Regel möglich ist, muss im Augenblick der Aktivierung ausdrücklich eine aktuelle Template-Regel existieren die »nicht-Null« ist.

Dies ist im Allgemeinen im Inneren einer Template-Regel stets der Fall, außer innerhalb einer xsl:for-each oder xsl:for-each-group-Instruktion. Hier wird der Current Node geändert, die aktuelle Template-Regel also vorüberge­hend auf null gesetzt. Sie ist erst nach Ausführung des entsprechenden Anwei­sungsblocks wieder gültig.

Achtung – nicht in xsl:for-each- oder xsl:for-each-group anwendbar!
Innerhalb von xsl:for-each- oder xsl:for-each-group-Anwei­sungsblöcken kann xsl:apply-imports nicht angewendet werden, da die aktuelle Template-Regel hier null ist. Der Versuch hat einen Laufzeitfehler (dynamic error) zur Folge.

Übergabe von Parameterwerten an aktivierte Template-Regeln:
In XSLT 1.0 ist xsl:apply-imports noch als leere Instruktion definiert. Seit XSLT 2.0 ist das Inhaltsmodell dahingehed erweitert, dass xsl:apply-imports eine oder mehrere xsl:with-param-Instruktionen enthalten darf, die Parameterwerte an die aktivierte Template-Regel übergeben können.

Eine tatsächliche Übergabe wird jedoch nicht forciert – im Gegensatz zur Parameterübergabe in xsl:call-template ist es kein Fehler, wenn im adressierten Template kein entsprechendes xsl:param-Element vorhanden ist.

Der aktuelle Satz von Tunnelparametern wird durch xsl:apply-imports in jedem Fall weitergegeben und ist demnach auch in den so aktivierten Templa­te-Regeln bzw. in von diesen ausgehend aktivierten Template-Regeln zugänglich.

Keine aktivierbare Template-Regel auffindbar:
Es ist kein Fehler, wenn keine aktivierbare importierte Template-Regel vorliegt – in diesem Fall verhält sich xsl:apply-imports identisch zu xsl:apply-templates. Exakter ausge­drückt: Es wird die eingebaute Default-Template-Regel aktiviert, die für Knoten vom Typ des Current Node zuständig ist.

In der Aktivierungsanweisung möglicherweise enthaltene xsl:with-param-Elemente werden in diesem Fall ignoriert. (Anmerkung: Dies ist analog zum Verhalten bei xsl:apply-templates und xsl:next-match.)

Die mächtige Alternative – xsl:next-match:
Seit XSLT 2.0 existiert eine xsl:apply-imports ergänzende Instruktion xsl:next-match, die ebenfalls deaktivierte Template-Regeln aufrufen kann. Im Gegensatz zu xsl:apply-imports ist xsl:next-match nicht nur dazu in der Lage, Regeln mit niedrige­rer Importpräzedenz zu aktivieren, sondern überdies auch solche mit nied­rigerer Priorität. Wie bei xsl:apply-imports muss die aktivierte Regel den gleichen Modus besitzen, der in der aktuellen Template-Regel gilt. Deaktivierte benannte Templates sind allerdings auch durch diese Instruktion nicht aufrufbar.

Beispiel – Aktivierung einer importierten Template-Regel:

Angenommen, es existiert ein externes Stylesheetmodul allgemein.xsl, das eine Tem­plate-Regel für ein Element <beispiel> besitzt:

<!-- Regel in externem Modul: -->
<xsl:template match="beispiel">
  <b>Beispiel: </b><xsl:apply-templates/>
</xsl:template>

Ein weiteres Stylesheet spezial.xsl (als Hauptmodul) könnte nun allge­mein.xsl importieren und durch Einsatz von xsl:apply-imports die Verar­beitung der Elemente <beispiel> wie folgt ergänzen:

<xsl:import href="spezial.xsl"/>
<!-- Regel im Hauptstylesheet: -->
<xsl:template match="beispiel">
  <div style="border: solid red">
    <!-- deaktivierte Template-Regel wird aufgerufen: -->
    <xsl:apply-imports/> 
  </div>
</xsl:template>

Beide zusammenwirkenden Stylesheets würden bei der Verar­beitung eines Elements <beispiel> folgende gemeinsame Wirkung erzielen:

<div style="border: solid red">
  <b>Beispiel: </b>
  ... [hier stehen Inhalte aus dem XML-Dokument] ...
</div>

Das Ergebnis entspricht der Verschachtelung beider Templateblöcke. Man kann sich den »reaktivierten« Template-Body als an der Stelle ins Haupt-Temp­late inkludiert vorstellen, an dem die Anweisung xsl:apply-imports steht.

Das Template des Hauptstylesheets »borgt« sich in diesem Fall die xsl:apply-templates-Anweisung des importierten Templates, um den Fortgang der Ver­arbeitung zu gewährleisten. Die xsl:apply-imports-Anweisung ersetzt quasi ein normalerweise hier stehendes xsl:apply-templates.

Elementdefinition:

XSLT 1.0:

<!-- Category: instruction -->
<xsl:apply-imports />

XSLT 2.0:

<!-- Category: instruction -->
<xsl:apply-imports>
  <!-- Content: xsl:with-param* -->
</xsl:apply-imports>
Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Galileo Press, Rheinwerkallee 4, 53227 Bonn