Importpräzedenz – Konfliktbewältigung bei Importen

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

Auch CSS-Stylesheets kennen das Konzept des Importierens von Style-­Anweisungen (Anmerkung: Siehe dazu Frank Bongers: »XHTML, HTML & CSS«, Galileo Press.) Durch Importe zusammengefasste CSS-Rules, die sich auf das­selbe Element beziehen, pflegen sich zu addieren. Im Fall von Konflikten zwi­schen sich widersprechenden Einzelregeln »gewinnt« die Anweisung im importierenden CSS-Stylesheet.

Ein vergleichbares Prinzip der Importpräzedenz gilt ebenso bei importierten XSLT-Stylesheets, dennoch ist die Ausgangslage bei XSLT eine andere, denn eine einfache Addition von Regeln findet nur in bestimmten Fällen statt.

Importieren vs. Inkludieren

Auch in XSLT ist man nicht darauf angewiesen, alles unbedingt in einem Style­sheet unterbringen zu müssen. Es gibt sogar gleich zwei einander ähnelnde Befehle, die externe Stylesheet-Module und ein Hauptstylesheet zusammen­bringen:

  • xsl:import
  • Diese Deklaration importiert externe Regeln und Deklarationen:

    <xsl:import href="pfad/externes_modul.xsl" />

  • xsl:include

  • Diese Deklaration inkludiert externe Regeln und Deklarationen:

    <xsl:include href="pfad/externes_modul.xsl" />

Beide Instruktionen sind stets leer und verwenden ein href-Attribut, um ein externes Stylesheetmodul zu laden. Auf den ersten Blick mutet das fast iden­tisch an, im Detail existieren allerdings Unterschiede, die die Lösung auftreten­der Konflikte betreffen.

Importieren mit xsl:import

Die erstgenannte der beiden Anweisungen – xsl:import – entspricht partiell dem Importvorgang bei CSS-Files. Jenen gegenüber besteht allerdings der gewaltige Unterschied, dass sich Templateregeln mit gleichem match-Attribut nicht etwa addieren. Bei derartigen Dubletten kommt sofort eine Importpräze­denz zum Tragen, mit der Folge, dass als niederrangiger eingestufte externe Templateregeln, die mit »lokalen« konkurrieren, verdeckt werden. Mehr dazu gleich.

Einfügen mit xsl:include

Im Gegensatz zu xsl:import, das die Informationen über Rang und Herkunft der externen Regeln berücksichtigt, entspricht xsl:include einem physi­schen Kopiervorgang. Hierbei gelten die externen Styleanweisungen als quasi am Ort der inkludierenden Instruktion geschrieben.

Die Position von xsl:include im Stylesheet (bzw. innerhalb eines Stylesheet­-Moduls) ist nicht reglementiert, abgesehen davon, dass es sich um ein Toplevel-Element handelt. Die Position der Inkludierungsanweisung ist insofern rele­vant, als dass bei auftretenden Dubletten von Templateregeln die letzte im Sty­lesheet in Dokumentreihenfolge auftretende Regel verwendet wird. Rückt man die Inkludierungsanweisung dementsprechend ans Ende des Stylesheets (bzw. eines Moduls), so können die inkludierten Regeln Vorrang bekommen, setzt man die Instruktion an den Anfang, so werden dies die lokal vorliegenden sein.

Die Templateregeln des inkludierten Moduls besitzen exakt die gleiche Importpräzedenz wie die lokalen Regeln des inkludierenden Stylesheets (dies ist im Wesentlichen dann von Bedeutung, wenn ein Stylesheetmodul, das ein anderes inkludiert, von einem weiteren importiert wird). Die inkludierten Regeln verhalten sich somit genau so, als ob sie in das Hauptstylesheet real ein­gefügt wären. Man kann es betrachten, als ob der Parser die xsl:include-Anweisung durch die gesamten externen Templateregeln ersetzt, und diese dann an dieser Stelle (d.h. am Beginn des Stylesheets!) zu stehen kommen.

Importieren von externen Stylesheets mit xsl:import

Ein xsl:import-Statement lädt ein externes Stylesheetmodul, dessen Template­regeln dann aber gegenüber den »lokalen« Templateregeln geringere Wertigkeit (niedrigere Importpräferenz) besitzen.

<xsl:import href="pfad/dateiname.xsl" />

Das Element xsl:import zählt zu den Toplevel-Elementen, darf also nicht innerhalb von Templateblöcken auftreten. Wird es eingesetzt, so muss es vor eventuellen xsl:include-Elementen und vor allen anderen Toplevel-Elemen­ten stehen. Mehrere xsl:import-Anweisungen dürfen dabei aufeinander fol­gen.

Für den Fall, dass in einem mit xsl:include inkludierten Stylesheet xsl:import-Anweisungen stehen, gelten diese, unabhängig von der tatsächli­chen Position der Inkludierunngsanweisung, als nach den letzten real im Hauptstylesheet stehenden xsl:import-Instruktionen geschrieben, rücken also gewissermaßen nach vorne.

Ein ansonsten sparsam gestaltetes Stylesheet fasst Templateanweisungen zur Formatierung eines Standardartikels mit solchen, zur Formatierung von Tabel­len benötigten, zusammen.

...
<!-- artikel-mit-tabelle.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="artikel.xsl"/>
  <xsl:import href="tabelle.xsl"/>
</xsl:stylesheet>

Das Stylesheet artikel.xsl könnte nun seinerseits wieder ein Stylesheet bil­der.xsl importieren, das die Templates zum Umgang mit Bildern enthält.

Man spricht von solcherart kaskadierten Importanweisungen als einem Importzweig (import tree). Alle in einem Zweig enthaltenen Stylesheets besit­zen ein Import-Child-Stylesheet für jedes xsl:import, das sie beinhalten. Diese xsl:import-Anweisungen werden ausgeführt, bevor der komplettierte Baum dem Hauptstylesheet hinzugefügt wird.

Oben würde somit das mitimportierte bilder.xsl dem Hauptstylesheet hin­zugefügt, bevor tabelle.xsl importiert wird.

Beispiel für die Importpräzedenz

Hier soll ein etwas komplexeres Szenario aufgeschlüsselt werden – in der Regel wird die Situation einfacher sein.

  • Modul 1 (master.xsl) importiert – in dieser Reihenfolge – Modul 4 und 2.
  • Modul 2 importiert wiederum Modul 3.
  • Modul 4 importiert – in dieser Reihenfolge – Modul 6 und 5.

Komplexes Szenario für Importpräzedenz

Abbildung: Komplexes Szenario für Importpräzedenz.

Die Rangfolge der Importpräzedenz der Regeln aus den Modulen entspricht dann, gelistet mit steigender Präzedenz: Modul 6 (niedrigste Präzedenz), dann Modul 5, Modul 4, Modul 3, Modul 2, schließlich Modul 1 (master.xsl, höchste Präzedenz).

  • Templateregeln aus Modul 1 haben Vorrang vor allen Templateregeln der anderen Stylesheetmodule.
    Die Reihenfolge des Auftretens der xsl:import-Anweisungen im Stylesheet ist entscheidend (in der Grafik durch graue Rechtecke markiert). Die zuletzt auftretende Anweisung hat die höchste Importpräzedenz; die dritte eine höhere als die zweite, diese eine höhere als die zuerst erfolgte – falls entsprechend viele vorhanden sind.
  • Der gesamte zuletzt importierte Zweig ist ranghöher.
    Importiert ein importiertes Stylesheetmodul seinerseits weitere Stylesheet­module, so ist die Importpräzedenz der mitimportierten Module niedriger als die des zunächst importierten – Module 5 und 6 haben einen geringeren Rang als das sie importierende Modul 4.
    Dabei ist aber der gesamte Importzweig immer noch höherrangiger als die­jenigen Module, die vor dem Wurzel-Modul des Zweigs ins Haupt­stylesheet importiert werden. Deshalb hat Modul 3 einen höheren Rang als Modul 4, obwohl Modul 4 unmittelbar und Modul 3 nur mittelbar importiert wird – aber eben durch das ranghöhere Stylesheetmodul 2.
  • Mehrfachimporte sind unkritisch.
    Es ist erlaubt – wenn auch nicht son­derlich sinnvoll – ein Stylesheet mehrmals zu importieren. Dessen Regeln treten dann sozusagen mehrfach mit unterschiedlicher Importpräzedenz auf. Bei komplexen Import­situationen kann dieser Fall durchaus auftreten, irgendwelche besonders hilfreichen Effekte lassen sich damit jedoch nicht erzielen.

   

<< zurück vor >>
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