Advanced Example

  • Revision slug: The_XSLT_JavaScript_Interface_in_Gecko/Advanced_Example
  • Revision title: Advanced Example
  • Revision id: 335511
  • Created:
  • Creator: Brettz9
  • Is current revision? No
  • Comment

Revision Content

Advanced Example

The advanced example will sort several divs based on their content. The example allows to sort the content multiple times, alternating between ascending and descending sorting. The JavaScript only loads the .xsl file the first time, and sets the xslloaded variable to true once it has finished loading the file. Using the getParameter method on the XSLTProcessor object, the code can figure wether to sort by ascending or descending. It defaults to ascending if the parameter is empty (first time the sorting happens, as there is no value for it in the XSLT file). The sorting value is set using 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 appened to the document, as shown in this example.

Figure 7 : Sorting based on div contentview 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>

// JavaScript

var xslRef;
var xslloaded = false;
var xsltProcessor = new XSLTProcessor();
var myDOM;

var xmlRef = document.implementation.createDocument("", "", null);

function sort() {
  if (!xslloaded){
    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
  var myNode = document.getElementById("example");
  var clonedNode = xmlRef.importNode(myNode, true);

  // after cloning, we append
  xmlRef.appendChild(clonedNode);

  // set the sorting parameter in the XSL file
  var sortVal = xsltProcessor.getParameter(null, "myOrder");

  if (sortVal == "" || sortVal == "descending")
    xsltProcessor.setParameter(null, "myOrder", "ascending");
  else
    xsltProcessor.setParameter(null, "myOrder", "descending");

  // initiate the transformation
  var fragment = xsltProcessor.transformToFragment(xmlRef, document);

  // clear the contents
  document.getElementById("example").innerHTML = "";

  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>

Revision Source

<h2 id="Advanced_Example" name="Advanced_Example">Advanced Example</h2>
<p>The advanced example will sort several divs based on their content. The example allows to sort the content multiple times, alternating between ascending and descending sorting. The JavaScript only loads the .xsl file the first time, and sets the <code>xslloaded</code> variable to true once it has finished loading the file. Using the <code>getParameter</code> method on the <code>XSLTProcessor</code> object, the code can figure wether to sort by ascending or descending. It defaults to ascending if the parameter is empty (first time the sorting happens, as there is no value for it in the XSLT file). The sorting value is set using <code>setParameter</code>.</p>
<p>The XSLT file has a parameter called <code>myOrder</code> that JavaScript sets to change the sorting method. The <code>xsl:sort</code> element's order attribute can access the value of the parameter using <code>$myOrder</code>. However, the value needs to be an XPATH expression and not a string, so <code>{$myOrder}</code> is used. Using {} evaluates the content as an XPath expression.</p>
<p>Once the transformation is complete, the result is appened to the document, as shown in this example.</p>
<p><small><b>Figure 7&nbsp;: Sorting based on div content<span class="comment">view example</span></b></small></p>
<pre class="brush: js">
// XHTML Fragment:

&lt;div id="example"&gt;
  &lt;div&gt;1&lt;/div&gt;
  &lt;div&gt;2&lt;/div&gt;
  &lt;div&gt;3&lt;/div&gt;
  &lt;div&gt;4&lt;/div&gt;
  &lt;div&gt;5&lt;/div&gt;
  &lt;div&gt;6&lt;/div&gt;
  &lt;div&gt;7&lt;/div&gt;
  &lt;div&gt;8&lt;/div&gt;
  &lt;div&gt;9&lt;/div&gt;
  &lt;div&gt;10&lt;/div&gt;
&lt;/div&gt;

// JavaScript

var xslRef;
var xslloaded = false;
var xsltProcessor = new XSLTProcessor();
var myDOM;

var xmlRef = document.implementation.createDocument("", "", null);

function sort() {
  if (!xslloaded){
    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
  var myNode = document.getElementById("example");
  var clonedNode = xmlRef.importNode(myNode, true);

  // after cloning, we append
  xmlRef.appendChild(clonedNode);

  // set the sorting parameter in the XSL file
  var sortVal = xsltProcessor.getParameter(null, "myOrder");

  if (sortVal == "" || sortVal == "descending")
    xsltProcessor.setParameter(null, "myOrder", "ascending");
  else
    xsltProcessor.setParameter(null, "myOrder", "descending");

  // initiate the transformation
  var fragment = xsltProcessor.transformToFragment(xmlRef, document);

  // clear the contents
  document.getElementById("example").innerHTML = "";

  myDOM = fragment;
  // add the new content from the transformation
  document.getElementById("example").appendChild(fragment)
}

// XSL Stylesheet:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
  &lt;xsl:output method="html" indent="yes" /&gt;

  &lt;xsl:param name="myOrder" /&gt;

  &lt;xsl:template match="/"&gt;

    &lt;xsl:apply-templates select="/div//div"&gt;
      &lt;xsl:sort select="." data-type="number" order="{$myOrder}" /&gt;
    &lt;/xsl:apply-templates&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template match="div"&gt;
    &lt;xsl:copy-of select="." /&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
Revert to this revision