Signatur
Beschreibung
document.createExpression() nimmt einen XPath-Ausdruck als Zeichenkette entgegen, prüft seine Syntax und gibt ein vorkompiliertes XPathExpression-Objekt zurück. Dessen Methode evaluate(contextNode, type, result) wertet den Ausdruck dann gegen einen beliebigen Knoten aus.
Gegenüber document.evaluate() lohnt sich die Methode vor allem, wenn derselbe Ausdruck mehrmals ausgewertet wird, etwa in Schleifen über viele Elemente oder bei der wiederholten Verarbeitung von XML-Antworten. Der Ausdruck wird nur einmal geparst, das spart Rechenzeit.
Enthält der Ausdruck Namensraum-Präfixe (z. B. svg:rect oder atom:entry), muss ein Namespace-Resolver übergeben werden. Das kann eine Funktion sein, die ein Präfix auf eine Namensraum-URI abbildet, ein Objekt mit einer Methode lookupNamespaceURI() oder ein Knoten (der Resolver übernimmt dann die Namensraum-Deklarationen dieses Knotens).
Ist der Ausdruck syntaktisch ungültig, wirft die Methode sofort eine DOMException vom Typ SyntaxError. Werden Präfixe verwendet, die sich nicht auflösen lassen, wird eine NamespaceError geworfen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $expression Pflicht | string | Der zu kompilierende XPath-1.0-Ausdruck, z. B. '//a[@href]'. |
|
| $resolver | XPathNSResolver | ((prefix: string | null) => string | null) | Node | null | null | Löst im Ausdruck verwendete Namensraum-Präfixe in URIs auf. Nur nötig, wenn der Ausdruck Präfixe enthält. |
Rückgabewert
evaluate(contextNode, type, result), die ein XPathResult liefert.Beispiele
Ausdruck einmal kompilieren, mehrfach auswerten
// Alle externen Links innerhalb jedes Artikels zählen
const expr = document.createExpression(
'count(.//a[starts-with(@href, "http")])'
);
for (const article of document.querySelectorAll('article')) {
const result = expr.evaluate(article, XPathResult.NUMBER_TYPE);
console.log(`${article.id}: ${result.numberValue} externe Links`);
}
Knotenliste per Snapshot durchlaufen
const expr = document.createExpression('//img[not(@alt)]');
const snapshot = expr.evaluate(
document,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);
for (let i = 0; i < snapshot.snapshotLength; i++) {
const img = snapshot.snapshotItem(i);
img.alt = ''; // Barrierefreiheit: leeres alt setzen
console.warn('Bild ohne alt:', img.src);
}
XML mit Namensräumen und Resolver-Funktion
const xml = `<feed xmlns="http://www.w3.org/2005/Atom">
<entry><title>Erster Beitrag</title></entry>
<entry><title>Zweiter Beitrag</title></entry>
</feed>`;
const doc = new DOMParser().parseFromString(xml, 'application/xml');
const ns = { atom: 'http://www.w3.org/2005/Atom' };
const expr = doc.createExpression(
'//atom:entry/atom:title',
(prefix) => ns[prefix] ?? null
);
const it = expr.evaluate(doc, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
let node;
while ((node = it.iterateNext())) {
console.log(node.textContent);
}
Ungültige Syntax abfangen
try {
document.createExpression('//div[@class=');
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Browser unterstützen nur XPath 1.0. Funktionen aus XPath 2.0/3.x wie
matches()oderlower-case()führen zu einemSyntaxError. - In HTML-Dokumenten werden Elementnamen ohne Präfix dem HTML-Namensraum zugeordnet. In XML-Dokumenten mit Standard-Namensraum (etwa Atom oder SVG) findet
//entrynichts. Hier braucht es ein Präfix und einen Resolver. - Ergebnisse vom Typ
*_ITERATOR_TYPEwerden ungültig, sobald sich das DOM ändert:iterateNext()wirft dann einenInvalidStateError. Wer Knoten beim Durchlaufen ändert, sollte*_SNAPSHOT_TYPEverwenden. - Stammen XPath-Ausdrücke aus Benutzereingaben, lassen sie sich manipulieren (XPath-Injection). Werte deshalb nie ungeprüft in Ausdrücke einsetzen.
- Die Methode wird in allen modernen Browsern unterstützt. In Node.js fehlt sie, dort sind Bibliotheken wie
jsdomoderxpathnötig. - Für einfache Abfragen ist
querySelectorAll()meist schneller und besser lesbar. XPath lohnt sich bei Achsen wieancestor::, bei Textabfragen oder bei Berechnungen wiecount().