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

Document.createNSResolver()

Methode

Erzeugt aus einem DOM-Knoten einen <code>XPathNSResolver</code>, der Namensraum-Präfixe in XPath-Ausdrücken anhand der Namensraum-Deklarationen dieses Knotens auflöst.

seit JavaScript DOM Level 3 XPath; Baseline: alle Browser (heute n deprecated seit ja Kategorie: webapi

Signatur

Document.prototype.createNSResolver(nodeResolver)

Beschreibung

createNSResolver() nimmt einen Knoten entgegen und gibt ein Objekt zurück, dessen Methode lookupNamespaceURI(prefix) für ein Präfix wie atom den passenden Namensraum-URI liefert. Die Auflösung richtet sich nach den xmlns:*-Deklarationen, die für diesen Knoten gelten. Das Ergebnis übergibt man als dritten Parameter an document.evaluate() oder XPathEvaluator.evaluate().

Man braucht die Methode vor allem für XPath-Abfragen auf XML-Dokumenten mit Namensräumen, etwa RSS/Atom-Feeds, SVG, XHTML, SOAP oder KML. Ohne Resolver lassen sich Präfixe wie svg:rect in XPath-Ausdrücken nicht auflösen, und es kommt zu einem NAMESPACE_ERR.

Nach der aktuellen DOM-Spezifikation gibt die Methode den übergebenen Knoten unverändert zurück. Jeder Node hat nämlich bereits eine Methode lookupNamespaceURI() und kann deshalb direkt als Resolver dienen. createNSResolver() gibt es also nur noch aus Kompatibilitätsgründen. In neuem Code übergibt man besser den Knoten selbst oder eine eigene Resolver-Funktion.

Parameter

Name Typ Default Beschreibung
$nodeResolver Pflicht Node Knoten, dessen Namensraum-Deklarationen (einschließlich der geerbten) zum Auflösen der Präfixe dienen. Meist ist das xmlDoc.documentElement.

Rückgabewert

Typ
XPathNSResolver | Node
Beschreibung
Ein Objekt mit der Methode lookupNamespaceURI(prefix). In aktuellen Browsern ist das der übergebene Knoten selbst.

Beispiele

Atom-Feed mit Namensraum per XPath abfragen

const xml = `<feed xmlns="http://www.w3.org/2005/Atom" xmlns:a="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 resolver = doc.createNSResolver(doc.documentElement);

const result = doc.evaluate(
  '//a:entry/a:title',
  doc,
  resolver,
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null
);

for (let i = 0; i < result.snapshotLength; i++) {
  console.log(result.snapshotItem(i).textContent);
}
Erster Beitrag Zweiter Beitrag

Präfix direkt über den Resolver nachschlagen

const doc = new DOMParser().parseFromString(
  '<root xmlns:svg="http://www.w3.org/2000/svg"/>',
  'application/xml'
);
const resolver = doc.createNSResolver(doc.documentElement);

console.log(resolver.lookupNamespaceURI('svg'));
console.log(resolver.lookupNamespaceURI('unbekannt'));
console.log(resolver === doc.documentElement); // aktuelle Browser
http://www.w3.org/2000/svg null true

Moderne Alternative: eigene Resolver-Funktion

const namespaces = {
  svg: 'http://www.w3.org/2000/svg',
  xlink: 'http://www.w3.org/1999/xlink'
};
const resolveNS = (prefix) => namespaces[prefix] ?? null;

const doc = new DOMParser().parseFromString(
  '<svg xmlns="http://www.w3.org/2000/svg"><rect width="10"/><rect width="20"/></svg>',
  'image/svg+xml'
);

const count = doc.evaluate(
  'count(//svg:rect)',
  doc,
  resolveNS,
  XPathResult.NUMBER_TYPE,
  null
).numberValue;

console.log(`Rechtecke: ${count}`);
Rechtecke: 2

// Wichtig · Fallstricke

  • Veraltet: Die Methode gibt es nur noch aus historischen Gründen und sie liefert den übergebenen Knoten zurück. Übergib stattdessen direkt einen Node oder eine Funktion (prefix) => uri an evaluate().
  • Standard-Namensraum: XPath 1.0 kennt keinen Standard-Namensraum. Elemente aus xmlns=\"…\" erreicht man nicht über //entry, sondern nur über ein Präfix wie //a:entry. Der Resolver auf Basis des Knotens liefert für ein selbst gewähltes Präfix aber nur dann einen URI, wenn es im Dokument auch deklariert ist. Sonst hilft nur eine eigene Resolver-Funktion.
  • In HTML-Dokumenten werden Namensraum-Präfixe normalerweise nicht gebraucht. Dort gibt man für den Resolver einfach null an.
  • Gibt der Resolver für ein Präfix null zurück, wirft evaluate() einen NAMESPACE_ERR (DOMException).
  • Kompatibilität: Die Methode wird in allen gängigen Browsern unterstützt. Node.js hat kein eingebautes DOM, dort braucht man Bibliotheken wie jsdom oder xmldom/xpath.