Die XSLT-Funktion unparsed-entity-uri()

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

Es gibt mehr oder weniger saubere Tricks, Bilder oder andere externe Ressour­cen einzubinden, ohne sie als Entities zu deklarieren. Angenommen, Sie dekla­rieren ein Element <bild> mit einem CDATA-Attribut quelle wie folgt:

<!ELEMENT bild EMPTY>
<!ATTLIST bild quelle CDATA #REQUIRED>

so kann im XML-Dokument Folgendes geschrieben werden:

<bild quelle="mein_bild.gif"/>

und durch eine XSLT-Transformation in ein HTML-<img> umgewandelt wer­den:

<xsl:template match="bild">
  <img src="{@quelle}"/>
</xsl:template>

Warum also sollten Sie das nicht so machen? Unter vielen Umständen spricht nichts dagegen, Pfad und Dateiname einfach als String zu übergeben, weil es schließlich funktioniert. Einfacher ist es auch. Es gibt allerdings mehrere Punkte zu bedenken:

  • Der Wert von quelle ist ein String, nicht mehr. Darüber hinaus ist CDATA der­art liberal, dass keine Reglementierung der Angabe ermöglicht ist.
  • Der Parser kann nicht prüfen, ob eine Ressource vorhanden ist, weil er inhalt­lich gar nicht die Möglichkeit hat, dies als Verweis zu erkennen.
  • Dateiname und Pfad müssen von Hand konstant gehalten werden, falls die Dokumente oder die Bilder relativ zueinander bewegt werden.

Was ist der Vorteil eines externen Entities?

Wie oben erwähnt, besteht zum einen die Möglichkeit, das Vorhandensein der Ressource zu überprüfen – ob der XML-Parser dies tut, hängt natürlich von sei­ner Programmierung ab. Die NOTATION-Deklaration könnte im Prinzip Infor­mationen über die Art der Weiterverarbeitung oder Darstellung liefern. Beide Gründe sind etwas schwach, da kaum eine Implementierung in dieser Richtung besteht.

Bleibt das Problem mit den Pfaden zwischen Dokument und Ressource. Liegen Dokument, DTD und Bild an verschiedenen Orten oder greift man mit einem XSLT-Prozess, der das Dokument selbst als externe Ressource verwendet, indi­rekt auf das Bild zu, so kann das Aufrechterhalten der Pfade »von Hand« schon zum Problem werden. Ist das Bild als unparsed Entity deklariert, so gibt es eine Lösung hierfür: unparsed-entity-uri().

Die XSLT-Funktion unparsed-entity-uri() kümmert sich um die Auflösung des Basis-URI und damit der Pfade zwischen Dokument und externer Ressource. Im einfachen Fall einer internen DTD ist ihr Rückgabewert der Pfad zwischen der Referenz und der Ressource, ergänzt um den Basis-URI des Stylesheets.

Die Funktion

Die Funktion stellt lediglich einen Befehl dar, der besagt: »Finde die zum Funk­tionsargument passende Entity-Deklaration, erzeuge einen URL zur Ressource und gib diesen als Stringwert zurück.«

Das Eingabeargument der Funktion ist ein Stringwert, nämlich der Entityname. Dieser String kann sich durch Auswertung eines XPath-Ausdrucks ergeben, der auf das Attribut zeigt, das diesen Entity-Bezeichner enthält.

Meist wird man die Funktion in einem Attributwert-Template einsetzen:

 <xsl:template match="bild">
   <img src="{unparsed-entity-uri(@quelle)}"/>
 </xsl:template>
  

Der Rückgabewert der Funktion entpricht dem Stringwert des zu erzeugendem URI.

Entity-Deklaration in interner oder externer DTD

Im einfachen Fall, wenn die DTD im Dokument steht, gibt die Funktion die absolute Adresse des XML-Dokuments aus (seinen Basis-URI) und hängt an diese den relativen Pfad zum Entity an.

Komplexer wird es, wenn eine externe DTD vorliegt. In diesem Fall ist nämlich der Pfad zum Entity, wie er in der DTD steht, relativ zur DTD zu verstehen – nicht relativ zum Dokument. Beim Ausführen der Funktion geht der Parser erneut von der Position des Dokuments aus, addiert hier den Pfad vom Doku­ment zur DTD und rechnet schließlich den Pfad von der DTD zum Entity dazu.

Dies funktioniert auch, wenn alle drei beteiligten Dateien in verschiedenen Verzeichnissen liegen. Auch wenn die Referenz auf das Entity nicht im Doku­ment, sondern in einem externen geparsten Entity stattfindet, ist dies egal. In letzterem Fall wird auch der Basis-URI des Textentities einbezogen.

Die Funktion addiert den Pfad zur DTD und von dort zum Bild

Abbildng: Die Funktion addiert den Pfad zur DTD und von dort zum Bild.

Indirekte Einbindung durch den XSLT-Prozess

Wie an verschiedenen Stellen bereits angedeutet, gibt es die Möglichkeit, wei­tere XML-Dokumente in einen Verarbeitungsprozess einzubeziehen. Dies geschieht aus dem XSLT-Stylesheet heraus (mit der Funktion document(), auf die wir an anderer Stelle zurückkommen werden).

Selbst in diesem Fall ist die unparsed-entity-uri()-Funktion in der Lage, einen funktionierenden Pfad zur Datei aufzubauen, indem die relative Lage aller beteiligten Dateien zueinander berücksichtigt wird.

Pfade zwischen beteiligten Dokumenten werden aufgelöst

Abbildung: Pfade zwischen beteiligten Dokumenten werden aufgelöst.

Dieses letzte Szenario soll hier dazu dienen, die Verwendung von »unparsed Entities« zu rechtfertigen. Es ist nicht so abwegig, wie es auf den ersten Blick scheinen mag. Voraussetzung für die Nutzung der Funktion ist natürlich in jedem Fall, dass eine DTD vorliegt (wo sie auch immer liegen mag) und dass das verarbeitende Programm auf diese Zugriff hat.

   

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