Signatur
Beschreibung
Mit new XPathEvaluator() bekommst du ein eigenständiges Objekt, das die Methoden evaluate(), createExpression() und createNSResolver() bereitstellt. Es macht dasselbe wie die gleichnamigen Methoden auf document, ist aber nicht an ein bestimmtes Dokument gebunden. Deshalb eignet es sich gut für Hilfsfunktionen oder Bibliotheken, die mit beliebigen Dokumenten arbeiten, z. B. mit einem XMLDocument aus DOMParser oder fetch().
Typische Anwendungsfälle sind das Auslesen von XML-Daten (RSS-Feeds, SVG, Konfigurationsdateien), gezielte Abfragen im HTML-DOM, die mit CSS-Selektoren nicht möglich sind (z. B. „Element mit einem bestimmten Textinhalt“ oder Navigation zum Elternelement), und Scraping-Skripte.
Wenn du denselben Ausdruck mehrfach auswertest, kompiliert createExpression() ihn einmal zu einem XPathExpression. Das spart das wiederholte Parsen.
Rückgabewert
XPathEvaluator-Objekt mit den Methoden evaluate(), createExpression() und createNSResolver().Beispiele
Evaluator erstellen und Links zählen
const evaluator = new XPathEvaluator();
const result = evaluator.evaluate(
'count(//a[@href])',
document,
null,
XPathResult.NUMBER_TYPE,
null
);
console.log(`Links auf der Seite: ${result.numberValue}`);
XML aus DOMParser mit vorkompiliertem Ausdruck auslesen
const xml = `<katalog>
<buch preis="19.90"><titel>JavaScript kompakt</titel></buch>
<buch preis="34.50"><titel>DOM im Detail</titel></buch>
</katalog>`;
const doc = new DOMParser().parseFromString(xml, 'application/xml');
const evaluator = new XPathEvaluator();
// Ausdruck einmal kompilieren, beliebig oft verwenden
const teureBuecher = evaluator.createExpression('//buch[@preis > 20]/titel', null);
const result = teureBuecher.evaluate(doc, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < result.snapshotLength; i++) {
console.log(result.snapshotItem(i).textContent);
}
Button anhand seines Textes finden (mit CSS nicht möglich)
const evaluator = new XPathEvaluator();
const findeButton = (text) =>
evaluator.evaluate(
`//button[normalize-space(.) = "${text}"]`,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue;
const btn = findeButton('Speichern');
console.log(btn ? 'Gefunden' : 'Nicht gefunden');
Namensräume mit eigenem Resolver auflösen
const svg = `<svg xmlns="http://www.w3.org/2000/svg"><circle r="5"/><circle r="9"/></svg>`;
const doc = new DOMParser().parseFromString(svg, 'image/svg+xml');
const evaluator = new XPathEvaluator();
const resolver = (prefix) => ({ svg: 'http://www.w3.org/2000/svg' })[prefix] ?? null;
const anzahl = evaluator.evaluate('count(//svg:circle)', doc, resolver, XPathResult.NUMBER_TYPE, null);
console.log(anzahl.numberValue);
// Wichtig · Fallstricke
- Kompatibilität: Wird in allen modernen Browsern unterstützt. Der Internet Explorer kannte kein
XPathEvaluator. In Node.js gibt es die Klasse nicht von Haus aus, dort brauchst du z. B.jsdomoder das Paketxpath. - Nur XPath 1.0: Browser implementieren ausschließlich XPath 1.0. Funktionen aus XPath 2.0/3.x wie
matches()oderlower-case()lösen einenSyntaxErroraus. - Namensräume: In XML-Dokumenten mit Standard-Namensraum (SVG, Atom, XHTML) findet
//circlenichts. Du musst ein Präfix verwenden und einen Namensraum-Resolver übergeben. - Veraltete Ergebnisse: Iterator-Ergebnisse (
*_ITERATOR_TYPE) werden ungültig, sobald sich das DOM ändert. Der nächste Aufruf voniterateNext()löst dann einenInvalidStateErroraus. Wenn du das DOM während der Schleife veränderst, nimm Snapshot-Typen. - Sicherheit: Baue Benutzereingaben nicht ungeprüft in XPath-Ausdrücke ein (XPath-Injection). Anführungszeichen können den Ausdruck verändern, deshalb Eingaben vorher maskieren oder validieren.
- Der Aufruf ohne
newlöst einenTypeErroraus.