Start · Sprachen · JavaScript · Referenz · DocumentType.replaceWith()

DocumentType.replaceWith()

Methode

Ersetzt den <code>DocumentType</code>-Knoten (die Doctype-Deklaration) im Elternknoten durch beliebig viele Knoten oder Zeichenketten.

seit JavaScript DOM Living Standard; Baseline: alle aktuellen Brow Kategorie: webapi

Signatur

DocumentType.prototype.replaceWith(...nodes)

Beschreibung

replaceWith() kommt aus dem Mixin ChildNode und steht deshalb auch auf DocumentType zur Verfügung. Die Methode entfernt den Doctype-Knoten aus seinem Elternknoten (in der Regel dem Document) und fügt an derselben Stelle die übergebenen Knoten ein. Zeichenketten werden dabei automatisch in Text-Knoten umgewandelt.

In der Praxis braucht man das vor allem dann, wenn man Dokumente programmgesteuert erzeugt oder umbaut, etwa XML-Dokumente aus DOMParser oder mit document.implementation.createDocument() erstellte Dokumente. Dort kann man eine veraltete DTD-Referenz durch einen neuen Doctype ersetzen oder den Doctype durch einen Kommentar austauschen, bevor man das Dokument mit XMLSerializer ausgibt.

Wichtig ist, dass die Knotenhierarchie des Dokuments eingehalten wird: Ein Document darf höchstens einen Doctype haben, der vor dem Wurzelelement stehen muss. Außerdem darf ein Dokument keine Text-Knoten als Kinder haben. Deshalb sind als Ersatz nur ein anderer DocumentType, Comment- oder ProcessingInstruction-Knoten sinnvoll. Alles andere führt zu einem HierarchyRequestError.

Parameter

Name Typ Default Beschreibung
$...nodes Node | string Beliebig viele Knoten oder Zeichenketten, die an die Stelle des Doctypes treten. Zeichenketten werden zu Text-Knoten und sind deshalb direkt unter einem Document nicht erlaubt. Ohne Argumente wird der Doctype einfach entfernt, genau wie mit remove().

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück. Die Änderung wirkt direkt auf den DOM-Baum.

Beispiele

Doctype des aktuellen Dokuments durch einen neuen ersetzen

const oldDoctype = document.doctype;

if (oldDoctype) {
  // Einfachen HTML5-Doctype erzeugen
  const html5 = document.implementation.createDocumentType('html', '', '');
  oldDoctype.replaceWith(html5);
}

console.log(document.doctype.name, JSON.stringify(document.doctype.publicId));
html ""

DTD-Referenz in einem XML-Dokument aktualisieren

const source = '<!DOCTYPE note SYSTEM "note.dtd"><note><to>Anna</to></note>';
const xml = new DOMParser().parseFromString(source, 'application/xml');

const newDoctype = xml.implementation.createDocumentType('note', '', 'note-v2.dtd');
xml.doctype.replaceWith(newDoctype);

console.log(new XMLSerializer().serializeToString(xml));
<!DOCTYPE note SYSTEM "note-v2.dtd"><note><to>Anna</to></note>

Doctype durch einen Kommentar ersetzen und Fehlerfall abfangen

const xml = new DOMParser().parseFromString(
  '<!DOCTYPE config SYSTEM "config.dtd"><config/>',
  'application/xml'
);

// Ein Kommentar ist als Kind von Document erlaubt
xml.doctype.replaceWith(xml.createComment(' DTD entfernt '));
console.log(xml.doctype); // kein Doctype mehr vorhanden
console.log(new XMLSerializer().serializeToString(xml));

// Ein String würde zu einem Text-Knoten werden und ist deshalb nicht erlaubt
const doc2 = new DOMParser().parseFromString('<!DOCTYPE a><a/>', 'application/xml');
try {
  doc2.doctype.replaceWith('Hallo');
} catch (err) {
  console.log(err.name);
}
null <!-- DTD entfernt --><config/> HierarchyRequestError

// Wichtig · Fallstricke

  • Doctype kann null sein: Hat das Dokument keinen Doctype, liefert document.doctype den Wert null. Prüfe das vor dem Aufruf oder verwende document.doctype?.replaceWith(...).
  • HierarchyRequestError: Diesen Fehler gibt es bei Zeichenketten und Text-Knoten, bei Elementen, wenn schon ein Wurzelelement existiert, bei einem zweiten Doctype und wenn ein Doctype hinter dem Wurzelelement landen würde.
  • Kein Einfluss auf den Rendermodus: Ob ein HTML-Dokument im Quirks- oder Standardmodus dargestellt wird, legt der Browser beim Parsen fest. Wenn du den Doctype später änderst, bleibt document.compatMode gleich.
  • Ist der Doctype an keinen Elternknoten angehängt, macht der Aufruf nichts.
  • Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt, aber nicht vom Internet Explorer. Dort bleibt nur parentNode.replaceChild().