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

XSLTProcessor.transformToFragment()

Methode

Wendet das importierte XSLT-Stylesheet auf einen Quellknoten an und gibt das Ergebnis als <code>DocumentFragment</code> zurück, das einem Zieldokument gehört.

seit JavaScript Baseline: alle modernen Browser (nicht in Node.js) deprecated seit ja Kategorie: webapi

Signatur

XSLTProcessor.prototype.transformToFragment(source, output)

Beschreibung

transformToFragment() führt die XSLT-Transformation eines XSLTProcessor aus. Vorher muss mit importStylesheet() ein Stylesheet geladen worden sein. Die Methode wendet es auf den Knoten source an und liefert das Ergebnis als DocumentFragment. Dessen Eigentümer (ownerDocument) ist das Dokument output.

Das passt gut, wenn Sie XML-Daten (z. B. aus fetch() oder DOMParser) direkt in die aktuelle HTML-Seite einfügen wollen. Übergeben Sie als output einfach document. Dann können Sie das Fragment ohne importNode() oder adoptNode() per append() oder appendChild() einhängen.

Wie die Knoten im Fragment erzeugt werden, hängt von <xsl:output method="…"> und vom Typ des Zieldokuments ab. Bei einem HTML-Dokument entstehen normalerweise HTML-Elemente. Bei method="text" enthält das Fragment nur einen Textknoten. Den Unterschied zu transformToDocument() sollten Sie kennen: Diese Methode erzeugt ein eigenständiges neues Dokument. transformToFragment() ist dagegen zum Einbetten gedacht.

Parameter

Name Typ Default Beschreibung
$source Pflicht Node Der Knoten, auf den das Stylesheet angewendet wird, meist ein XMLDocument oder ein Element daraus.
$output Pflicht Document Das Dokument, dem das erzeugte DocumentFragment gehören soll, in der Regel document.

Rückgabewert

Typ
DocumentFragment
Beschreibung
Ein DocumentFragment mit dem Ergebnis der Transformation. Es gehört zu output. In einigen Browsern kommt bei einem Fehler null zurück, in anderen wird eine Ausnahme ausgelöst.

Beispiele

XML-Daten per XSLT als HTML-Liste einfügen

const parser = new DOMParser();

const xml = parser.parseFromString(`
  <buecher>
    <buch><titel>Faust</titel></buch>
    <buch><titel>Die Räuber</titel></buch>
  </buecher>`, 'application/xml');

const xsl = parser.parseFromString(`
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>
    <xsl:template match="/">
      <ul>
        <xsl:for-each select="buecher/buch">
          <li><xsl:value-of select="titel"/></li>
        </xsl:for-each>
      </ul>
    </xsl:template>
  </xsl:stylesheet>`, 'application/xml');

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

const fragment = processor.transformToFragment(xml, document);
document.body.append(fragment);
console.log(document.body.lastElementChild.outerHTML);
<ul><li>Faust</li><li>Die Räuber</li></ul>

XML und XSL per fetch laden und mit Parameter transformieren

const loadXml = async (url) => {
  const text = await (await fetch(url)).text();
  return new DOMParser().parseFromString(text, 'application/xml');
};

const render = async () => {
  const [data, stylesheet] = await Promise.all([
    loadXml('/daten/produkte.xml'),
    loadXml('/xsl/produkte.xsl')
  ]);

  const processor = new XSLTProcessor();
  processor.importStylesheet(stylesheet);
  // entspricht <xsl:param name="kategorie"/> im Stylesheet
  processor.setParameter(null, 'kategorie', 'Bücher');

  const fragment = processor.transformToFragment(data, document);
  if (!fragment) throw new Error('Transformation fehlgeschlagen');

  document.querySelector('#produkte').replaceChildren(fragment);
};

render().catch(console.error);

Textausgabe mit method="text"

const parser = new DOMParser();
const xml = parser.parseFromString('<p><n>Anna</n><n>Ben</n></p>', 'application/xml');
const xsl = parser.parseFromString(`
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
      <xsl:for-each select="p/n"><xsl:value-of select="."/>;</xsl:for-each>
    </xsl:template>
  </xsl:stylesheet>`, 'application/xml');

const proc = new XSLTProcessor();
proc.importStylesheet(xsl);
const frag = proc.transformToFragment(xml, document);
console.log(frag.textContent);
Anna;Ben;

// Wichtig · Fallstricke

  • Nur XSLT 1.0: Browser unterstützen weder XSLT 2.0/3.0 noch die meisten EXSLT-Erweiterungen. document() und xsl:import unterliegen der Same-Origin-Policy.
  • Fehlerbehandlung ist uneinheitlich: Je nach Browser liefert die Methode bei einem ungültigen Stylesheet null oder löst eine Ausnahme aus. Prüfen Sie deshalb beides. Außerdem müssen Sie nach dem Parsen prüfen, ob DOMParser ein <parsererror>-Element erzeugt hat.
  • Ohne importStylesheet() gibt es keine gültige Transformation.
  • Sicherheit: Das Ergebnis wird als echtes DOM eingefügt. Stammen XML-Daten oder Stylesheet aus nicht vertrauenswürdigen Quellen, kann das zu XSS führen, etwa durch erzeugte on*-Attribute oder javascript:-Links. Verwenden Sie deshalb nur Stylesheets, denen Sie vertrauen. Ungeprüfte Nutzerdaten sollten Sie nicht mit disable-output-escaping ausgeben.
  • Kompatibilität: Die Methode ist in allen modernen Browsern verfügbar, aber nicht in Node.js und nicht in Web Workern. Die Browser-Hersteller diskutieren, XSLT künftig einzuschränken oder zu entfernen. Für neue Projekte ist JavaScript-Templating deshalb meist zukunftssicherer.
  • Das Fragment ist nach dem Einfügen leer, denn seine Kinder werden verschoben.