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.
Figure 7: Sorting based on div content: view example
XHTML Fragment:
<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>
JS Fragment:
let xslRef; let xslloaded = false; const xsltProcessor = new XSLTProcessor(); let myDOM; let xmlRef = document.implementation.createDocument("", "", null); function sort() { if (!xslloaded) { const p = new XMLHttpRequest(); p.open("GET", "example2.xsl", false); p.send(null); xslRef = p.responseXML; 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) }
XSL Stylesheet:
<?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>