Dass eine leere Knotenmenge, wie oben erwähnt, für einen XPointer-Ausdruck einen Fehler bedeutet, liegt daran, dass XPointer zwar die Syntax von XPath übernimmt, aber im Gegensatz zu XSLT kein Anfrage-Mechanismus ist. Vielmehr geht es in XPointer um die Suche nach Orten im Dokument. Dabei kann es auch um Bereiche gehen, die sich über Elementgrenzen oder Teilbäume erstrecken.
Das heißt, XPointer erfordern mehr als XPath
bietet. Zum Beispiel: Dokumentteile zu identifizieren, die
nicht Knoten sind. Um dies zu erreichen, definiert der
XPointer-Entwurf den Ort location als eine
Erweiterung des Knotens in XPath: Sie kann außerdem ein
Punkt oder ein Bereich im obigen Sinne sein. Analog
dazu ist Ortsmenge (location-set) die
Erweiterung zur Knotenmenge in
XPathOrt
und Ortsmenge
erscheinen uns nicht als ideale Übersetzungen, Bereich ist
schon für die range reserviert, und ein Punkt ist
nun einmal ein Punkt..
Die Erweiterung des XPath-Knotens bezieht sich auch auf den Zusammenhang, innerhalb dessen ein XPointer ausgewertet wird. Für diese Auswertung setzt der Entwurf Rahmenbedingungen. Zu Beginn der Aktion ist der Ort (context location) auf den Wurzelknoten (/) gesetzt. Die Kontextposition ist 1, die Kontextgröße ebenfalls. Funktionen dürfen nur dann benutzt werden, wenn sie entweder in XPath oder in Xpointer definiert sind (siehe unten). Schließlich: Innerhalb des Auswertungskontextes müssen Namensräume so deklariert sein, dass sie für XPointer erreichbar sind.
Die beiden Erweiterungen des Knoten-Konzepts, wie es in XPath gilt, sind eine der wesentlichen Änderungen, die der XPointer-Entwurf vorsieht. Punkt (point) und Bereich (range) sind neben dem Knoten weitere Ortstypen, die wiederum in Ortsmengen vorkommen — und auf die man mit XPath-Ausdrücken (im genannten erweiterten Sinn) zugreifen kann.
NodeType | ||||
---|---|---|---|---|
|
Der Entwurf will zwar ausdrücklich keine Vorgaben für die Implementierung von Punkten machen, definiert sie aber durchaus: Ein Punkt besteht aus einem Behälterknoten (container node) und Index (größer oder gleich Null). Für den Fall, dass der Behälterknoten ein Element oder der Wurzelknoten ist und selbst Kindknoten haben kann, ist der Index einer, der die Kinder zählt. Einen solchen Punkt nennt man Knotenpunkt (node point). Vor dem ersten Kindknoten hat der Index den Wert 0, nach dem dritten Kindelement beträgt er 3.
Handelt es sich bei dem Behälterknoten hingegen um einen, der nicht selbst Kindkoten haben kann — er heißt dann sinnigerweise Zeichenknoten (character node), bezeichnet der Index die Position eines Zeichens. Ist er 0, heißt das: Der Punkt ist direkt vor dem ersten Zeichen der Zeichenkette angesiedelt (etwa im Falle eines Attributs). Und analog zum Knotenpunkt bedeutet ein Index von 3 den Punkt nach dem dritten Zeichen. Daran ist zu sehen, das ein Punkt nicht selbst Zeichenwerte hat, sondern nur eine Position beschreibt.
Nach den bisherigen Ausführungen leuchtet es sicherlich ein, dass ein Bereich (range) durch zwei Punkte definiert ist. Es dürfte sich hier um einen der am schwierigsten zu implementierenden Teile des Entwurfs handeln, denn ein solcher Bereich überschreitet die Grenzen von Knoten (Elementen, Attributen, ...), den Basisbausteinen von XML-Dokumenten. Und ein solcher Bereich kann mitten in einem Knoten anfangen, nur durch den Anfangspunkt bezeichnet, der wenig überraschend vor dem Endpunkt stehen muss (beide im selben Dokument; über diese Grenze geht der Bereich nicht hinaus).
Handelt es sich sowohl beim Anfangs- als auch beim Endpunkt um Zeichenpunkte (siehe oben) und sind die Behälterknoten identisch, besteht der Zeicheninhalt des Bereichs aus der durch beide Punkte begrenzten Zeichenkette. Anderenfalls bilden die Zeichen aller Textknoten innerhalb des Bereichs die Zeichenkette.
Wer einen Blick zurück auf die Produktionsregel für den Fragmentbezeichner wirft, findet dort in Regel [7], dass ein XPointer-Ausdruck entweder aus einem in XPath definierten Ausdruck besteht — oder aus einem, den erst der XPointer-Entwurf definiert.
Range Expression | ||||
---|---|---|---|---|
|
Auch hier fängt die Bearbeitung beim Ausdruck links an; sie muss eine Ortsmenge als Ergebnis haben. Anschließend wird für jeden Ort a in dieser Menge der zweite Ausdruck (mit dem Kontext-Ort a, der Kontext-Position 1 und der Kontextgöße 1) ausgewertet. Dabei muss jedes Ergebnis wiederum eine Ortsmenge sein. Zeit für ein Beispiel.
xpointer(id("abschnitt2.1")/descendant::P[last()] to id("abschnitt2.2")/descendant::P[last()])
Das dem XPointer-Entwurf entnommene Listing
bewirkt, dass eine Anwendung alles vom letzten Absatz
(P[last()]) des Abschnitts mit der
ID abschnitt2.1
bis zum letzten Absatz
des Abschnitts mit der ID
abschnitt2.2
auswählt. Dies Beispiel erstreckt sich
wahrscheinlich über eine recht große Menge an
Knoten.
Xpointer enthält einige Funktionen, die über XPath hinausgehen. XPointer-Implementierungen müssen sie umsetzen. Wo es in der folgenden Tabelle nicht ausdrücklich erwähnt ist, haben sie den Rückgabewert Ortsmenge (location-set). Die erste Funktion ist die bedeutendste.
Funktion | Bedeutung |
---|---|
string-range(location-set string number? number?) | Sucht in jedem Ort der Ortsmenge (1. Parameter) nach der Zeichenkette (2.); die beiden Zahlen benennen den Anfang (Default: 1)und die Länge des gesuchten Bereichs (Default: bis zum Ende) — Beispiel: string-range(//P, "Am Anfang war")[3] ergibt das dritte Vorkommen der Zeichenkette in einem Absatz (P) |
range(location-set) | Orte im Argument |
range-inside(location-set) | Inhalt von Orten im Argument |
start-point(location-set) | Rückgabe eines oder mehrerer Punkte; ein Startpunkt für jeden Ort im Argument — Beispiel: start-point(//kapitel[3]) bezeichnet den Punkt direkt vor Kapitel 3 |
end-point(location-set) | Rückgabe eines oder mehrerer Punkte; ein Start-Punkt für jeden Ort im Argument — Beispiel: end-point(//kapitel[3]) bezeichnet den Punkt direkt nach Kapitel 3 |
here() | Rückgabe eines Elements als Ortsmenge |
origin() | Rückgabe des Elements, von dem eine Verzweigung ausging |
boolean unique() | Rückgabe des Wertes wahrfür den Fall, dass die Kontextgröße=1 ist (sonst unwahr) |
Es ist möglich, dass diese Liste in der endgültigen Spezifikation nicht die aktuelle ist.