Vorab eine Warnung. Wie die erweiterten Links sind
auch die in diesem Abschnitt behandelten XPointer noch nicht
verabschiedet. Das mag aber der Fall sein, wenn Sie dies
lesen, denn gelegentlich
geht die Entwicklung beim
W3C recht schnell voran. Zum Zeitpunkt der
Fertigstellung dieses Buches waren beide Entwürfe (XLink und XPointer), zwar
schon im sogenannten Last-Call-Status, aber in beiden Fällen
scheint es intern noch Diskussionen zu geben.
Sind erweiterte Links aus HTML-Sicht schon eine deutliche Verbesserung, so bieten die XPointer Möglichkeiten, auf Dokumentteile zuzugreifen, die noch weit darüber hinausgehen. Dazu bedienen sich die XPointer der am Anfang dieses Kapitels erwähnten Möglichkeit, einem URI nach dem Fragmentbezeichner ('#') etwas folgen zu lassen: An ihn schließt sich ein XPointer an. Anders ausgedrückt: In XML müssen die dem Fragmentbezeichner folgenden Zeichen immer einen XPointer darstellen. Vorkehrungen dafür, dass auf etwas verwiesen werden kann, sind in den XML-Dokumenten nicht notwendigerweise zu treffen (kein <A NAME="ABD"> mehr).
Ein paar spezielle Begriffe müssen wir den Definitionen vom Anfang des Kapitels hinzufügen, damit klar ist, welche wir wie verwenden.
Originalbezeichnung | deutsche Übersetzung | Erklärung |
---|---|---|
axis | Achse | Folge von Daten, die XPointer nutzt (Beispiel: alle Kindelemente) |
location | Ort | Vergleichbar dem Knoten in XPath, kann hier aber auch ein Punkt oder Bereich sein |
location set | Ortsmenge | Geordnete Liste aus dem, was ein XPointer-Ausdruck ergibt; vergleichbar der Knotenmenge in XPath, hier aber ergänzt um Punkt und Bereich |
predicate | Prädikat | Boolscher Ausdruck; von XPointer dazu genutzt Teil-Ressourcen im Verhältnis zu anderen auszuwählen |
point | Punkt | Ort im Dokument |
range | Bereich | Auswahl aus dem gesamten Inhalt zwischen zwei Punkten |
Zu den Achsen ist zu sagen, dass sie sich auf die aus Kapitel 7 bekannten beziehen. Hier folgt eine Kurzübersicht.
Achse | bezieht sich auf |
---|---|
child | Kinder des Kontextknotens |
descendant | Nachfahren des Kontextknotens |
parent | Direkter Vorfahr des Kontextknotens, so vorhanden |
ancestor | Vorfahren des Kontextknotens |
following-sibling | Alle Geschwister des Kontextknotens nach ihm |
preceding-sibling | Alle Geschwisterknoten des Kontextknotens vor ihm |
following | Alle Knoten im Dokument nach dem gegenwärtigen in der Dokumentreihenfolge |
preceding | Alle Knoten im Dokument vor dem gegenwärtigen in der Dokumentreihenfolge |
attribute | Attribute des Kontextknotens |
namespace | Die Namensraumknoten des Kontextknotens |
self | Nur der Kontextknoten |
descendant-or-self | Der Kontextknoten selbst und seine Nachfahren |
ancestor-or-self | Der Kontextknoten selbst und seine Vorfahren |
XPointer beschreiben einen Ort oder Bereich innerhalb einer XML-Instanz. Um dies zu tun, bedienen sie sich der Struktur der einzelnen Dokumente. Nach dem Fragementbezeichner in einem einfachen Link wie <mylink xlink:type="simple" xlink:href=mydoc.xml#...> könnten folgende Ausdrücke stehen:
xpointer(id('a1001')) id('a1001') xpointer(buch/kapitel/abschnitt[position() = last() and @class='wichtig'])
Das sind die einfachsten Xpointer-Beispiele: Die
ersten beiden verweisen beide auf das Element mit der
— per definitionem immer eindeutigen —
id a1001
. Das dritte zielt auf den
jeweils letzten Abschnitt von Kapiteln in einem Buch, die
ein Attribut class mit dem Wert
wichtig
haben. Schon hier ist zu sehen, dass die
Verweismöglichkeiten von XPointer sich nicht nur auf
Elemente mit Attributen vom Typ ID beziehen,
sondern auf beliebige Elemente (und Elementteile) sowie
Attribute.
Xpointer bauen auf der XML Path Language auf, die Kapitel 7 darstellt. XPath, so die Kurzform, ist eine Sprache, die außer in den XPointern unter anderem in XSLT (siehe Kapitel 10) zum Einsatz kommt. XPointer sind so angelegt, dass sie außer Element(teilen) auch Punkte (point) und Bereichen (range) ansprechen können. Darüber hinaus ist es möglich, über den Vergleich von Zeichenketten Textstellen zu finden und innerhalb von Fragmentbezeichnern Ausdrücke, wie sie XPath vorsieht, zu verwenden.
In der Backus-Naur-Form ist zu erkennen, dass es drei Arten gibt, wie sich XPointer ausdrücken lassen: entweder ein Name, eine Kindfolge oder ein Fragment.
XPointerFragID | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Die vollständige Form eines XPointer-Ausdrucks [3] beginnt mit der Zeichenkette xpointer oder einem anderen Scheme (den zweiten Fall deckt der Entwurf nicht ab, sieht ihn vor allem für die Zukunft vor). Dem xpointer folgt in Klammern ein Ausdruck (XPointerExpr), der entweder [7] denen aus XPath entspricht (Expr) oder eine XPointer-Erweiterung ist (RangeExpr).
Aus Gründen der Abwärtskompatibilität sieht der
Entwurf die Möglichkeit vor, XPointer wie in HTML
anzugeben: mydoc.xml#a1001. In diesem Fall steht
der Fragmentbezeichner implizit für eine ID und
schreibt sich als XPointer eigentlich
#id('a1001'). Außerdem
ermöglicht XPointer es, auf Elemente durch Aufschreiben ihres
Ortes zuzugreifen: Dafür steht die Kindfolge
(ChildSeq). Auf diese Weise lassen sich Elemente
— nicht Attribute oder andere Knoten — über
Schrägstriche und Ziffern ansprechen. /1 etwa steht
für das unter dem Wurzelknoten angesiedelte
(Dokumenttyp-)Element.
Generell gilt für XPointer, dass sie, wenn sie in XML-Dokumenten vorkommen, das Kleinerzeichen und das &-Zeichen nur in maskierter Form beinhalten dürfen (< und &).
Auf die Regel [6] oben bezogen, existiert eine Gültigkeitsbeschränkung: Klammern und das Caret, die hier eine Bedeutung haben, müssen, maskiert werden, wenn man ihnen diese Bedeutung nehmen und sie als normale Zeichen verwenden will. Beiden muss in solchen Fällen ein Caret vorangestellt sein (^(, ^) und ^^). Auch für Regel [7] existiert eine Gültigkeitsbeschränkung. Expr muss immer eine Knotenmenge zurückgeben.
Wie das Pluszeichen im Diagramm [1] oben zum Ausdruck
bringt, kann ein XPointer-Fragmentbezeichner mehrere
GeneralFragmentPart- Bestandteile haben. Und da die
Spezifikation derzeit nur ein Schema vorsieht, das der
XPointerExpr vorangehen kann (xpointer
),
heißt das, es kann mehrere mit xpointer beginnende
Ausdrücke in einem Fragmentbezeichner geben. Wenn mehrere
vorhanden sind, wie im folgenden Beispiel, werden sie von links
nach rechts abgearbeitet.
<!-- DTD --> <!element kapitel (...)> <!attlist kapitel id ID #REQUIRED> <!-- XPointer --> xpointer(id('kapitel11'))xpointer(//*[@id="kapitel11"])
Dieser dem Entwurf entnommene Fragmentbezeichner sorgt
dafür, dass die XPointer-Implementierung zunächst nach einem
Element sucht, dessen id den Wert
kapitel11 hat. Findet sie ein solches Element, ist
die Suche beendet. Da es sein kann, dass keine
DTD vorliegt, findet die Software das Element
nicht — möglicherweise ist, anders als in obigem
Beispiel selbst ein Attribut id
nicht einmal als ID deklariert. In diesem Fall
kommt das zweite GeneralFragmentPart zum Einsatz,
und die Software sucht nun nur
noch nach einem Attribut
id eines Elements (//*
steht für alle Elemente an beliebiger Stelle des Dokuments),
das den Wert kapitel11 hat.
Für die XPointer sind mehrere Fehlerklassen definiert, die jeweils charakterisieren, wo der Fehler entstanden ist; allerdings ist derzeit noch keine Fehlerbehandlung vorgesehen.
Die letzte Fehlerart deutet an, dass es Unterschiede zwischen XPath und XPointer geben könne. Dem ist richtig: XPointer beinhaltet ein paar Erweiterungen gegenüber Xpath.