Signatur
Beschreibung
createExpression() übersetzt einen XPath-Ausdruck als Zeichenkette in ein vorkompiliertes XPathExpression-Objekt. Anschließend führt man mit dessen Methode evaluate(contextNode, type, result) Abfragen aus, ohne dass der Ausdruck jedes Mal neu geparst wird.
Das lohnt sich vor allem, wenn derselbe Ausdruck oft ausgewertet wird, zum Beispiel in Schleifen über viele Knoten, bei der Verarbeitung großer XML-Dokumente oder bei wiederholten Abfragen auf dynamisch geänderten DOM-Bäumen. Für einmalige Abfragen reicht meist document.evaluate().
Die Methode gibt es auf XPathEvaluator-Instanzen (new XPathEvaluator()) und genauso direkt auf document, weil Document die gleiche Schnittstelle umsetzt. Nutzt der Ausdruck Namensraum-Präfixe (etwa bei XHTML, SVG oder eigenen XML-Formaten), muss als zweites Argument ein Namespace-Resolver übergeben werden, der Präfixe auf Namensraum-URIs abbildet.
Syntaktische Fehler im Ausdruck fallen schon beim Kompilieren auf: createExpression() wirft dann sofort eine DOMException, und zwar nicht erst beim Auswerten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $expression Pflicht | string | Der zu kompilierende XPath-Ausdruck (XPath 1.0), z. B. //li[@class='aktiv']. |
|
| $resolver | XPathNSResolver | ((prefix: string) => string | null) | null | null | Löst Namensraum-Präfixe im Ausdruck auf. Möglich sind eine Funktion, ein Objekt mit Methode lookupNamespaceURI(prefix) oder ein DOM-Knoten (etwa das Ergebnis von createNSResolver()). Für Ausdrücke ohne Präfixe kann man ihn weglassen oder null übergeben. |
Rückgabewert
XPathExpression-Objekt. Seine Methode evaluate(contextNode, type, result) liefert ein XPathResult.Beispiele
Ausdruck einmal kompilieren, mehrfach auswerten
const evaluator = new XPathEvaluator();
const expr = evaluator.createExpression('.//a[@href]');
// Links in jedem Artikel zählen – der Ausdruck wird nur einmal geparst
for (const article of document.querySelectorAll('article')) {
const result = expr.evaluate(article, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
console.log(`${article.id}: ${result.snapshotLength} Links`);
}
Zahlenwert aus einem XML-Dokument berechnen
const xml = new DOMParser().parseFromString(
`<bestellung>
<posten preis="12.5" menge="2"/>
<posten preis="4" menge="3"/>
</bestellung>`,
'application/xml'
);
const summePreise = document.createExpression('sum(//posten/@preis)');
const anzahl = document.createExpression('count(//posten)');
const summe = summePreise.evaluate(xml, XPathResult.NUMBER_TYPE).numberValue;
const n = anzahl.evaluate(xml, XPathResult.NUMBER_TYPE).numberValue;
console.log(summe, n);
Namensräume mit einem Resolver auflösen
const xml = new DOMParser().parseFromString(
`<feed xmlns="http://www.w3.org/2005/Atom">
<entry><title>Erster Beitrag</title></entry>
<entry><title>Zweiter Beitrag</title></entry>
</feed>`,
'application/xml'
);
const ns = { atom: 'http://www.w3.org/2005/Atom' };
const resolver = (prefix) => ns[prefix] ?? null;
const expr = new XPathEvaluator().createExpression('//atom:entry/atom:title', resolver);
const it = expr.evaluate(xml, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
let node;
while ((node = it.iterateNext())) {
console.log(node.textContent);
}
Syntaxfehler früh abfangen
const compile = (xpath) => {
try {
return document.createExpression(xpath);
} catch (err) {
console.error(`Ungültiger XPath "${xpath}": ${err.name}`);
return null;
}
};
compile('//div[@id=');
// Wichtig · Fallstricke
- Nur XPath 1.0: Browser können ausschließlich XPath 1.0. Funktionen aus XPath 2.0 und neuer (z. B.
matches(),lower-case()) werfen einen Fehler. - Standard-Namensraum: Hat ein XML-Dokument einen Standard-Namensraum (
xmlns="…"), findet//entrynichts. Man muss ein Präfix verwenden und es über den Resolver auflösen. In HTML-Dokumenten, die alstext/htmlgeladen wurden, ist das bei HTML-Elementen nicht nötig. - Fehlerarten: Ungültige Syntax führt zu einer
DOMExceptionvom TypSyntaxError. Ein nicht auflösbares Präfix führt zuNamespaceError. - Iterator-Ergebnisse: Ändert sich das DOM, während man über ein
*_ITERATOR_TYPE-Ergebnis läuft, wird der Iterator ungültig unditerateNext()wirft einen Fehler. Wer das DOM verändert, sollte*_SNAPSHOT_TYPEverwenden. - Sicherheit: Baut man Ausdrücke aus Benutzereingaben per String-Verkettung, ist XPath-Injection möglich. Werte sollten korrekt maskiert werden, besonders Anführungszeichen.
- In allen modernen Browsern verfügbar. Node.js hat die Methode nicht eingebaut, dort braucht man Bibliotheken wie
jsdomoderxpath.