XSLTProcessor
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
An XSLTProcessor
applies an XSLT stylesheet transformation to an XML document to
produce a new XML document as output. It has methods to load the XSLT stylesheet, to
manipulate <xsl:param>
parameter values, and to apply the
transformation to documents.
Constructor
XSLTProcessor()
-
Create a new
XSLTProcessor
.
Instance methods
XSLTProcessor.importStylesheet()
-
Imports the XSLT stylesheet. If the given node is a document node, you can pass in a full XSL Transform or a literal result element transform; otherwise, it must be an
<xsl:stylesheet>
or<xsl:transform>
element. XSLTProcessor.transformToFragment()
-
Transforms the node source by applying the XSLT stylesheet imported using the
XSLTProcessor.importStylesheet()
function. The owner document of the resulting document fragment is the owner node. XSLTProcessor.transformToDocument()
-
Transforms the node source applying the XSLT stylesheet given importing using the
XSLTProcessor.importStylesheet()
function. XSLTProcessor.setParameter()
-
Sets a parameter (
<xsl:param>
) value in the XSLT stylesheet that was imported. XSLTProcessor.getParameter()
-
Gets the value of a parameter from the XSLT stylesheet.
XSLTProcessor.removeParameter()
-
Removes the parameter if it was previously set. This will make the
XSLTProcessor
use the default value for the parameter as specified in the XSLT stylesheet. XSLTProcessor.clearParameters()
-
Removes all set parameters from the
XSLTProcessor
. TheXSLTProcessor
will then use the default values specified in the XSLT stylesheet. XSLTProcessor.reset()
-
Removes all parameters and stylesheets from the
XSLTProcessor
.
Instance properties
This are no properties for this interface.
Examples
Instantiating an XSLTProcessor
async function init() {
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
// Load the XSLT file, example1.xsl
const xslResponse = await fetch("example1.xsl");
const xslText = await xslResponse.text();
const xslStylesheet = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslStylesheet);
// process the file
// ...
}
Creating an XML document based on part of a document's DOM
For the actual transformation, XSLTProcessor
requires an XML document, which is used in conjunction with the imported XSL file to produce the final result. The XML document can be a separate XML file loaded using fetch()
, or it can be part of the existing page.
To process part of a page's DOM, it is necessary to first create an XML document in memory. Assuming that the DOM to be processed is contained by an element with the id example
, that DOM can be "cloned" using the in-memory XML document's Document.importNode()
method. Document.importNode()
allows transferring a DOM fragment between documents, in this case from an HTML document to an XML document. The first parameter references the DOM node to clone. By making the second parameter "true", it will clone all descendants as well (a deep clone). The cloned DOM can then be inserted into the XML document using Node.appendChild()
, as shown below.
// Create a new XML document in memory
const xmlRef = document.implementation.createDocument("", "", null);
// We want to move a part of the DOM from an HTML document to an XML document.
// importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
const myNode = document.getElementById("example");
const clonedNode = xmlRef.importNode(myNode, true);
// Add the cloned DOM into the XML document
xmlRef.appendChild(clonedNode);
Once the stylesheet has been imported, XSLTProcessor
has to perform two methods for the actual transformation, namely XSLTProcessor.transformToDocument()
and XSLTProcessor.transformToFragment()
. XSLTProcessor.transformToDocument()
returns a full XML document while XSLTProcessor.transformToFragment()
returns a document fragment that can be easily added to an existing document. Both take in the XML document as the first parameter that will be transformed. XSLTProcessor.transformToFragment()
requires a second parameter, namely the document object that will own the generated fragment. If the generated fragment will be inserted into the current HTML document, passing in document is enough.
Creating an XML document From a String 'XML Soup'
You can use the DOMParser
to create an XML document from a string of XML.
const parser = new DOMParser();
const doc = parser.parseFromString(aStr, "text/xml");
Performing the transformation
const fragment = xsltProcessor.transformToFragment(xmlRef, document);
Basic Example
The basic example will load an XML file and apply a XSL transformation on it. These are the same files used in the Generating HTML example. The XML file describes an article and the XSL file formats the information for display.
XML
<?xml version="1.0"?>
<myNS:Article xmlns:myNS="http://devedge.netscape.com/2002/de">
<myNS:Title>My Article</myNS:Title>
<myNS:Authors>
<myNS:Author company="Foopy Corp.">Mr. Foo</myNS:Author>
<myNS:Author>Mr. Bar</myNS:Author>
</myNS:Authors>
<myNS:Body>
The <b>rain</b> in <u>Spain</u> stays mainly in the plains.
</myNS:Body>
</myNS:Article>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myNS="http://devedge.netscape.com/2002/de">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<title>
<xsl:value-of select="/myNS:Article/myNS:Title"/>
</title>
<style>
.myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
</style>
</head>
<body>
<p class="myBox">
<span class="title">
<xsl:value-of select="/myNS:Article/myNS:Title"/>
</span> <br />
Authors: <br />
<xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
</p>
<p class="myBox">
<xsl:apply-templates select="//myNS:Body"/>
</p>
</body>
</html>
</xsl:template>
<xsl:template match="myNS:Author">
-- <xsl:value-of select="." />
<xsl:if test="@company">
:: <b> <xsl:value-of select="@company" /> </b>
</xsl:if>
<br />
</xsl:template>
<xsl:template match="myNS:Body">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The example loads both the .xsl (xslStylesheet
) and the .xml (xmlDoc
) files into memory. The .xsl file is then imported (xsltProcessor.importStylesheet(xslStylesheet)
) and the transformation run (xsltProcessor.transformToFragment(xmlDoc, document)
). This allows fetching of data after the page has been loaded, without initiating a fresh page load.
JavaScript
async function init() {
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
// Load the XSLT file, example1.xsl
const xslResponse = await fetch("example1.xsl");
const xslText = await xslResponse.text();
const xslStylesheet = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslStylesheet);
// Load the XML file, example1.xml
const xmlResponse = await fetch("example1.xml");
const xmlText = await xmlResponse.text();
const xmlDoc = parser.parseFromString(xmlText, "application/xml");
const fragment = xsltProcessor.transformToFragment(xmlDoc, document);
document.getElementById("example").textContent = "";
document.getElementById("example").appendChild(fragment);
}
init();
Advanced example
This advanced example sorts several divs based on their content. The example allows sorting the content multiple times, alternating between ascending and descending order. The JavaScript loads the .xsl file only on the first sort and sets the xslLoaded
variable to true once it has finished loading the file. Using the XSLTProcessor.getParameter()
method, the code can figure whether to sort in ascending or descending order. It defaults to ascending if the parameter is empty (the first time the sorting happens, as there is no value for it in the XSLT file). The sorting value is set using XSLTProcessor.setParameter()
.
The XSLT file has a parameter called myOrder
that JavaScript sets to change the sorting method. The xsl:sort
element's order attribute can access the value of the parameter using $myOrder
. However, the value needs to be an XPATH expression and not a string, so {$myOrder}
is used. Using {} evaluates the content as an XPath expression.
Once the transformation is complete, the result is appended to the document, as shown in this example.
XHTML
<div id="example">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
JavaScript
let xslRef;
let xslLoaded = false;
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
let myDOM;
let xmlRef = document.implementation.createDocument("", "", null);
async function sort() {
if (!xslLoaded) {
const response = await fetch("example2.xsl");
const xslText = await response.text();
xslRef = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslRef);
xslLoaded = true;
}
// Create a new XML document in memory
xmlRef = document.implementation.createDocument("", "", null);
// We want to move a part of the DOM from an HTML document to an XML document.
// importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
const myNode = document.getElementById("example");
const clonedNode = xmlRef.importNode(myNode, true);
// After cloning, we append
xmlRef.appendChild(clonedNode);
// Set the sorting parameter in the XSL file
const sortVal = xsltProcessor.getParameter(null, "myOrder");
if (sortVal === "" || sortVal === "descending") {
xsltProcessor.setParameter(null, "myOrder", "ascending");
} else {
xsltProcessor.setParameter(null, "myOrder", "descending");
}
// Initiate the transformation
const fragment = xsltProcessor.transformToFragment(xmlRef, document);
// Clear the contents
document.getElementById("example").textContent = "";
myDOM = fragment;
// Add the new content from the transformation
document.getElementById("example").appendChild(fragment);
}
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:param name="myOrder" />
<xsl:template match="/">
<xsl:apply-templates select="/div//div">
<xsl:sort select="." data-type="number" order="{$myOrder}" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="div">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
Specifications
Specification |
---|
DOM Standard # interface-xsltprocessor |
Browser compatibility
BCD tables only load in the browser