XSLT in the web browser — simple transformations on the server
Lets see how to make XSLT transformations in the web browser via a server
Applying XSLT in browser from the filesystem?
It used to be the case that a XML document could be associated with an XSLT stylesheet and the transformation could be applied like so:
<?xml-stylesheet type="text/xsl" href="example.xsl"?>
…Then you could open the XML document in the web browser, from the local filesystem and then the transformation would apply.
However, many revisions of browsers ago, this functionality to apply the transformation in the browser — when using files from the local filesystem — was stopped. This is because of Cross Origin Resource Sharing (CORS) which puts limits on how files are accessed from the local filesystem or different domains.
There are ways to get around this by adjusting browser settings but this is not recommended from a security perspective — you could forget to turn these settings back on and open yourselves to a vulnerability when using the browser.
To be accurate, it is not the XSLT transformation itself that is prevented by CORS, rather that the local files are prevented from being opened within the browser.
As a result of this change, to apply XSLT transformations in the browser, it is necessary to provide XML and XSLT documents via a server.
Apache web server
There are many different servers that can be used to serve XML based files, a popular choice for website development is the Apache web server and generally on Linux you may find this is installed already — if you haven’t already got a web server, downloading Apache2 is as easy as:
sudo apt-get install apache2
To apply the transformation you open the XML file in the browser and the transformation should be visible. The files should be in the part of filesystem that is accessible, in Linux systems this is usually /var/www/html/.
If your XML and XSLT were stored in /var/www/html/data/, you would just enter localhost/data/example.xml and the transformation will be visible.
To get the XSLT transformation to work you will still need to provide an association to the stylesheet as mentioned previously:
<?xml-stylesheet type="text/xsl" href="example.xsl" ?>
Note, on Linux systems, if the transformation is not applied you may have to check the file permissions. Using the terminal you can use chgrp and chmod however you need to provide the right permissions. If you are not the systems administrator you should check the right permissions to apply!
sudo chgrp [group] example.xml
sudo chmod 666 example.xml
On a public server you would want to lock down the files to read only, but whilst editing from the localhost, having the user with write access makes life a bit easier, for example if you navigate to the directory above the data folder, you could set the user for all files within the directory.
sudo chgrp [group] ./data -R
Be careful setting permissions for directories — as user you need the execute flag.
In your web-browser, if you simply view source of the transformation you’ll see the XML file without the XSLT transformation applied. The browser won’t show the transformation in view-source, but if you open up the browsers interactive development tools you will see the transformation and be able to navigate through this.
Alternatively, in Firefox you can select the text output in the browser, right click and select “View Selection Source”.
What you might find with using this method to apply transformations is that the XSLT file may be cached and if you make changes to the XSLT file they are not applied.
In Firefox developer tools there is a option within the browser to disable cache which is useful to see. Firefox developer tools will also show you which files are cached as not all files are, you can apply the option selectively.
PHP web server — local testing only
An alternative and overlooked web service for easy local use to test, but not for public facing websites, is to use the built in PHP web server.
You may not have realized that PHP provides a very basic web server. If you already have PHP installed, this can be additionally downloaded using the PHP command line interface.
sudo apt install php8.1-cli
Once installed, using this webserver is as simple as setting the below in the terminal:
php -S localhost:8000
Entering localhost:8000/ in your web browser should then serve the files within /var/www/html
To load a specific directory on web server startup, append the terminal instruction like so. If the directory has a space in the directory name, you will need to use quotes to declare the name.
php -S localhost:8000 -t "1. simple example"/
Running XSLT using Javascript — XSLTProcessor()
Now lets see a more likely way of applying an XSLT transformation in the browser — loading XML and XSLT files via XMLHttpRequest and applying the transformation with the XSLT Processor API.
On the caniuse.com website this feature is listed as supported on a variety of mainstream browsers however the website also notes “this feature is non-standard and should not be used without careful consideration. If you made a website that generated XSLT on the fly you might find some users not able to see the transformation.
Using XSLTProcessor to apply a transformation requires loading a file of document type XMLDocument — you can do this using ‘AJAX’ XMLHttpRequest() or fetch() or a Javascript library such as jQuery. We will explore using these in subsequent posts.
You will also require the XML and XSLT documents to be served using a local web server such as Apache.
It’s sensible to test first if the browser has XSLTProcessor() available. To do this we can test the window object for the string ’XSLTProcessor’ and then provide an update in the browser console if available.
(function(){
if (!('XSLTProcessor' in window)) {
console.log('XSLTProcessor does not appear to be available in this browser. Please try another.');
return;
}else{
console.log('XSLTProcessor available.');
}
});
Here is an example of loading an XSLT and XML file into two XMLDocuments using XMLHttpRequest(), importing the XSLT stylesheet, then transforming the XML document using XSLTProcessor() and appending the resulting transformation to a <div id=”example”></div>
The two key methods here are xsltProcessor.importStylesheet(xslDoc), which imports the XSLT stylesheet into the XSLTProcessor the xsltProcessor.transformToFragment(xmlDoc, document); which applies the XSLT transformation.
To find out more about XSLTProcessor and its methods, Mozilla Developer Networks — XSLTProcessor — Web APIs | MDN has a fully comprehensive overview.
Example 1 — XMLHttpRequest() and XSLTProcessor()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>XSLT</title>
</head>
<body>
<div id="example"></div>
<script type="text/javascript">
(function(){
if(!('XSLTProcessor' in window)) {
console.log('XSLTProcessor does not appear to be available in this browser. Please try another.');
return;
}else{
console.log('XSLTProcessor available.');
}
const xsltProcessor = new XSLTProcessor();
const xslRequest = new XMLHttpRequest();
//load the XSL file
//true as third parameter indicates asynchronous request
xslRequest.open("GET", "data/example.xsl", true);
xslRequest.addEventListener("load", function() {
if(xslRequest.readyState == 4){
if(xslRequest.status == 200){
const xslDoc = xslRequest.responseXML;
xsltProcessor.importStylesheet(xslDoc);
}
}
});
xslRequest.send(null);
// load the XML file
const xmlRequest = new XMLHttpRequest();
//true as third parameter indicates asynchronous request
xmlRequest.open("GET", "data/example.xml", true);
xmlRequest.addEventListener("load", function() {
if(xmlRequest.readyState == 4){
if(xmlRequest.status == 200){
const xmlDoc = xmlRequest.responseXML;
const fragment = xsltProcessor.transformToFragment(xmlDoc, document);
document.getElementById("example").appendChild(fragment);
}
}
});
xmlRequest.send(null);
})();
</script>
</body>
</html>
Next time, we’ll look at how to use jQuery to do load the XML and XSLT files.
My articles so far on XSLT for the Modern Web:
- Beginners XSLT patterns explained — simple key lookup
- What is XSLT and is it still relevant in a website context in 2024?
- XSLT in the web browser — simple transformations on the server
- Using jQuery with XSLT — .ajax(), .ajax() with Promises, .get()
- XSLT with Fetch() API — modern Javascript with/without Async and Await