Signatur
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): einXMLDocument.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
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));
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);
// 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
nullzurück, Firefox wirft eine Ausnahme. Prüfe deshalb immer beides (try/catchundnull). Prüfe außerdem vorher, obDOMParserein<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()oderadoptNode(), oder nutze gleichtransformToFragment(). - 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
XSLTProcessornicht. Dort brauchst du Bibliotheken wiexslt-processorodersaxon-js.