Signatur
Beschreibung
Die Methode evaluate() einer XPathExpression wertet einen XPath-Ausdruck aus, den Sie vorher mit document.createExpression() (bzw. XPathEvaluator.prototype.createExpression()) kompiliert haben. Ausgewertet wird relativ zum übergebenen Kontextknoten. Das Ergebnis ist ein XPathResult-Objekt, dessen Form über den Parameter type festgelegt wird.
Der Vorteil gegenüber document.evaluate(): Der Ausdruck wird nur einmal geparst und kann danach beliebig oft auf verschiedene Knoten angewendet werden. Das lohnt sich, wenn Sie denselben Ausdruck in einer Schleife auf viele Elemente anwenden oder große XML-Dokumente verarbeiten, etwa Antworten von DOMParser oder fetch().
Je nach Ergebnistyp lesen Sie den Wert über numberValue, stringValue, booleanValue, singleNodeValue, iterateNext() oder snapshotItem() / snapshotLength aus. Mit XPathResult.ANY_TYPE (0) wählt der Browser den passenden Typ selbst. Namensräume müssen Sie schon beim Erzeugen des Ausdrucks über einen Namespace-Resolver angeben, nicht erst beim Aufruf von evaluate().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $contextNode Pflicht | Node | Knoten, relativ zu dem der Ausdruck ausgewertet wird, z. B. document oder ein Element. Relative Pfade wie ./li beziehen sich auf diesen Knoten. |
|
| $type | number | XPathResult.ANY_TYPE (0) | Gewünschter Ergebnistyp als Konstante von XPathResult, z. B. NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE, UNORDERED_NODE_ITERATOR_TYPE, ORDERED_NODE_SNAPSHOT_TYPE oder FIRST_ORDERED_NODE_TYPE. |
| $result | XPathResult | null | null | Ein vorhandenes XPathResult, das wiederverwendet werden darf. Browser ignorieren den Parameter in der Praxis meist; null übergeben. |
Rückgabewert
XPathResult mit dem Ergebnis des angegebenen Typs. Bei ANY_TYPE steht der tatsächliche Typ in resultType.Beispiele
Ausdruck kompilieren und Absätze zählen
// Einmal kompilieren, dann auswerten
const expr = document.createExpression('count(//p)', null);
const result = expr.evaluate(document, XPathResult.NUMBER_TYPE, null);
console.log(`Absätze: ${result.numberValue}`);
Denselben Ausdruck auf viele Kontextknoten anwenden
// Für jede Liste den Text des ersten Eintrags ermitteln
const firstItem = document.createExpression('string(./li[1])', null);
for (const list of document.querySelectorAll('ul')) {
const res = firstItem.evaluate(list, XPathResult.STRING_TYPE, null);
console.log(res.stringValue.trim());
}
Knoten als Snapshot sammeln und verändern
const expr = document.createExpression('//a[starts-with(@href, "http")]', null);
const snap = expr.evaluate(document, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// Snapshot bleibt stabil, auch wenn das DOM verändert wird
for (let i = 0; i < snap.snapshotLength; i++) {
const link = snap.snapshotItem(i);
link.target = '_blank';
link.rel = 'noopener';
}
console.log(`${snap.snapshotLength} externe Links angepasst`);
XML mit Namensraum aus fetch() auswerten
const res = await fetch('/feed.atom');
const xml = new DOMParser().parseFromString(await res.text(), 'application/xml');
const resolver = (prefix) => ({ atom: 'http://www.w3.org/2005/Atom' })[prefix] ?? null;
const titles = xml.createExpression('//atom:entry/atom:title', resolver);
const it = titles.evaluate(xml, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
let node;
while ((node = it.iterateNext())) {
console.log(node.textContent);
}
// Wichtig · Fallstricke
- Iteratoren werden ungültig: Ändern Sie das Dokument, während Sie über ein
*_ITERATOR_TYPE-Ergebnis laufen, wirftiterateNext()einenInvalidStateError. Wenn Sie Knoten verändern wollen, nehmen Sie*_SNAPSHOT_TYPE. - Falscher Zugriff: Lesen Sie eine Eigenschaft, die nicht zum Ergebnistyp passt (z. B.
stringValuebei einem Knoten-Snapshot), wird einTypeErrorgeworfen. - Typumwandlung: Lässt sich das Ergebnis nicht in den angeforderten
typeumwandeln (etwa eine Zahl in eine Knotenmenge), wird ebenfalls einTypeErrorgeworfen. - Namensräume: In XHTML- oder XML-Dokumenten mit Standard-Namensraum finden Pfade ohne Präfix nichts. Den Resolver übergeben Sie bei
createExpression(). In normalen HTML-Dokumenten ist das nicht nötig. - Browser unterstützen nur XPath 1.0, keine Funktionen aus XPath 2.0/3.x wie
matches()oderlower-case(). - Die Methode gibt es in allen modernen Browsern, nicht aber in Node.js ohne DOM-Bibliothek (z. B. jsdom oder xpath).