Start · Sprachen · JavaScript · Referenz · Document.createExpression()

Document.createExpression()

Methode

Kompiliert einen XPath-Ausdruck zu einem <code>XPathExpression</code>-Objekt, das sich danach beliebig oft und effizient auf verschiedene Kontextknoten anwenden lässt.

seit JavaScript Baseline: alle Browser (DOM Level 3 XPath) Kategorie: webapi

Signatur

Document.prototype.createExpression(expression, resolver)

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

Typ
XPathExpression
Beschreibung
Ein kompiliertes Ausdrucksobjekt mit der Methode 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`);
}
intro: 3 externe Links fazit: 1 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);
}
Bild ohne alt: https://example.com/logo.png

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);
}
Erster Beitrag Zweiter Beitrag

Ungültige Syntax abfangen

try {
  document.createExpression('//div[@class=');
} catch (err) {
  console.log(err.name);
}
SyntaxError

// Wichtig · Fallstricke

  • Browser unterstützen nur XPath 1.0. Funktionen aus XPath 2.0/3.x wie matches() oder lower-case() führen zu einem SyntaxError.
  • In HTML-Dokumenten werden Elementnamen ohne Präfix dem HTML-Namensraum zugeordnet. In XML-Dokumenten mit Standard-Namensraum (etwa Atom oder SVG) findet //entry nichts. Hier braucht es ein Präfix und einen Resolver.
  • Ergebnisse vom Typ *_ITERATOR_TYPE werden ungültig, sobald sich das DOM ändert: iterateNext() wirft dann einen InvalidStateError. Wer Knoten beim Durchlaufen ändert, sollte *_SNAPSHOT_TYPE verwenden.
  • 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 jsdom oder xpath nötig.
  • Für einfache Abfragen ist querySelectorAll() meist schneller und besser lesbar. XPath lohnt sich bei Achsen wie ancestor::, bei Textabfragen oder bei Berechnungen wie count().