Start · Sprachen · JavaScript · Referenz · XSLTProcessor.transformToDocument()

XSLTProcessor.transformToDocument()

Methode

Wendet das importierte XSLT-Stylesheet auf einen Knoten an und gibt das Ergebnis als neues, eigenständiges <code>Document</code> zurück.

seit JavaScript Baseline: alle Browser (Entfernung in Chromium ang deprecated seit ja Kategorie: webapi

Signatur

XSLTProcessor.prototype.transformToDocument(source)

Beschreibung

transformToDocument() führt eine XSLT-1.0-Transformation aus. Das Stylesheet muss vorher mit XSLTProcessor.prototype.importStylesheet() geladen worden sein. Als Quelle dient ein beliebiger DOM-Node, meist ein per DOMParser oder fetch() geladenes XML-Dokument oder eines seiner Elemente.

Anders als transformToFragment() erzeugt die Methode ein vollständiges, neues Dokument, das keinem bestehenden Dokument gehört. Das eignet sich, wenn du das Ergebnis weiterverarbeiten willst, zum Beispiel serialisieren, mit XPath abfragen oder herunterladen. Willst du das Ergebnis direkt in die aktuelle Seite einfügen, ist transformToFragment(source, document) meist die bessere Wahl.

Welche Art von Dokument du bekommst, hängt von <xsl:output method="..."> ab:

  • xml (Standard): ein XMLDocument.
  • html: ein HTML-Dokument. Die Elemente liegen dann im HTML-Namensraum.
  • text: je nach Browser ein XML-Dokument mit einem einzigen Wrapper-Element, das den Text enthält (in Firefox zum Beispiel <transformiix:result>).

Parameter

Name Typ Default Beschreibung
$source Pflicht Node Der Knoten, auf den das Stylesheet angewendet wird, meist ein Document oder Element. Er ist der Kontextknoten der Transformation.

Rückgabewert

Typ
Document | null
Beschreibung
Ein neues Document mit dem Ergebnis der Transformation. Schlägt sie fehl, geben manche Browser null zurück (z. B. Chromium), andere werfen eine Ausnahme (z. B. Firefox).

Beispiele

XML-String transformieren und serialisieren

const xml = `<buecher>
  <buch><titel>Faust</titel><autor>Goethe</autor></buch>
  <buch><titel>Die Räuber</titel><autor>Schiller</autor></buch>
</buecher>`;

const xsl = `<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <autoren>
      <xsl:for-each select="buecher/buch">
        <name><xsl:value-of select="autor"/></name>
      </xsl:for-each>
    </autoren>
  </xsl:template>
</xsl:stylesheet>`;

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xml, 'application/xml');
const xslDoc = parser.parseFromString(xsl, 'application/xml');

const processor = new XSLTProcessor();
processor.importStylesheet(xslDoc);

const result = processor.transformToDocument(xmlDoc);
console.log(new XMLSerializer().serializeToString(result));
<autoren><name>Goethe</name><name>Schiller</name></autoren>

XML und XSL per fetch laden, HTML-Ergebnis in die Seite übernehmen

const loadXml = async (url) => {
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status} bei ${url}`);
  return new DOMParser().parseFromString(await res.text(), 'application/xml');
};

const renderReport = async () => {
  const [data, stylesheet] = await Promise.all([
    loadXml('/daten/bericht.xml'),
    loadXml('/xsl/bericht.xsl') // enthält <xsl:output method="html"/>
  ]);

  const processor = new XSLTProcessor();
  processor.importStylesheet(stylesheet);

  const resultDoc = processor.transformToDocument(data);
  if (!resultDoc) throw new Error('Transformation fehlgeschlagen');

  // Knoten aus fremdem Dokument vor dem Einfügen übernehmen
  const table = document.importNode(resultDoc.querySelector('table'), true);
  document.querySelector('#bericht').replaceChildren(table);
};

renderReport().catch(console.error);

Stylesheet-Parameter mit setParameter() übergeben

const xsl = `<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="gruss" select="'Hallo'"/>
  <xsl:template match="/person">
    <nachricht><xsl:value-of select="concat($gruss, ', ', name)"/></nachricht>
  </xsl:template>
</xsl:stylesheet>`;

const parser = new DOMParser();
const processor = new XSLTProcessor();
processor.importStylesheet(parser.parseFromString(xsl, 'application/xml'));
processor.setParameter(null, 'gruss', 'Guten Tag');

const source = parser.parseFromString('<person><name>Anna</name></person>', 'application/xml');
const out = processor.transformToDocument(source);
console.log(out.documentElement.textContent);
Guten Tag, Anna

// Wichtig · Fallstricke

  • Nur XSLT 1.0: Browser können nur XSLT 1.0 und XPath 1.0. Funktionen aus XSLT 2.0/3.0 (z. B. xsl:for-each-group, reguläre Ausdrücke) führen zu Fehlern.
  • Fehlerverhalten ist uneinheitlich: Chromium und WebKit geben bei Fehlern oft stillschweigend null zurück, Firefox wirft eine Ausnahme. Prüfe deshalb immer beides (try/catch und null). Prüfe außerdem vorher, ob DOMParser ein <parsererror>-Dokument geliefert hat.
  • Ohne importiertes Stylesheet schlägt der Aufruf fehl. Rufe zuerst importStylesheet() auf.
  • Fremdes Dokument: Die Knoten im Ergebnis gehören zu einem neuen Dokument. Übernimm sie vor dem Einfügen in die Seite mit document.importNode() oder adoptNode(), oder nutze gleich transformToFragment().
  • Sicherheit: Stylesheets aus nicht vertrauenswürdigen Quellen können beliebiges Markup erzeugen, auch <script> und Event-Attribute. Füge ein solches Ergebnis nur bereinigt in die Seite ein, sonst droht XSS. Stylesheets und XML-Daten von anderen Ursprüngen unterliegen beim Laden den CORS-Regeln.
  • Zukunft ungewiss: Das Chromium-Team hat angekündigt, XSLT im Browser zu entfernen, und auch andere Hersteller diskutieren darüber. Setze in neuen Projekten auf eine Transformation auf dem Server oder eine JavaScript-Bibliothek und prüfe vorher, ob XSLTProcessor überhaupt vorhanden ist: 'XSLTProcessor' in window.
  • In Node.js gibt es XSLTProcessor nicht. Dort brauchst du Bibliotheken wie xslt-processor oder saxon-js.