Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Most XSLT processors offer some way to tell them: "here is the source document and here is the stylesheet to use when processing it." For a command-line XSLT processor, the document and stylesheet are usually two different parameters specified at the command line.

Web browsers, however, usually read a document from a web server and have no way to separately be told about the stylesheet to apply. To remedy this, the W3C Recommendation Associating Style Sheets with XML Documents describes a processing instruction to include at the beginning of a document to name a stylesheet to apply to that document. For example, the processing instruction in the following numbers.xml document tells an application to apply the stylesheet squareAsHTML.xsl to that document.

<?xml-stylesheet href="squareAsHTML.xsl" type="text/xsl" ?>
<numbers>
  <number>2</number>
  <number>11</number>
  <number>100</number>  
  <number>-5</number>
</numbers>

This processing instruction must be at the very beginning of a document, unless there is an XML declaration before it. Below is the squareAsHTML.xsl stylesheet referenced by the processing instruction above:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<!-- squareAsHTML.xsl: create an HTML document with a statement
     about the square of each "number" element read from the
     source tree. -->

  <xsl:template match="/"> <!-- Set up web page -->
    <html>
      <head>
        <title>Squares</title>
        <style> <!-- Put a little CSS in -->
           body { font-family: arial,helvetica; }
           h1   { font-size: 14pt }
           p    { font-size: 10pt}
        </style>
      </head>
      <body>
        <h1>Squares</h1>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="number">
    <xsl:variable name="value" select="."/>
    <p>
      <xsl:text>The square of </xsl:text>
      <xsl:value-of select="$value"/>
      <xsl:text> is </xsl:text>
      <xsl:value-of select="$value * $value"/>.</p>
  </xsl:template>

</xsl:stylesheet>

(If you're using XSLT to create result documents with processing instructions in them, see the earlier column XSLT, Comments and Processing Instructions for information on XSLT's xsl:processing-instruction instruction.) Using a command-line XSLT processor such as Saxon or Xalan to apply the squareAsHTML.xsl stylesheet to the numbers.xml document creates the following HTML document:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Squares</title><style> 
           body { font-family: arial,helvetica; }
           h1   { font-size: 14pt }
           p    { font-size: 10pt}
        </style></head>
   <body>
      <h1>Squares</h1>
      <p>The square of 2 is 4.</p>
      <p>The square of 11 is 121.</p>
      <p>The square of 100 is 10000.</p>  
      <p>The square of -5 is 25.</p>
   </body>
</html>

Related Reading

XSLT Cookbook
Solutions and Examples for XML and XSLT Developers
By Sal Mangano

The best thing about specifying a document's stylesheet with this xml-stylesheet processing instruction is that it lets you use the document and designated stylesheet with a web browser. With the numbers.xml document and stylesheet shown above both sitting in the same directory of your hard disk, you can tell the current versions of Mozilla and Internet Explorer to open up numbers.xml and you'll see the result of the transformation. The rendered result should look the same as if you had opened an HTML file created by a command-line XSLT processor using the same input and stylesheet files. (The command-line processor Saxon does let you specify a command-line switch telling it to look for the stylesheet name in this processing instruction.)

You could also put the XML document and stylesheet on a web server, as I did here. Follow that link, and you should see the result of the stylesheet being applied to the XML document. After doing so, try a View Source, and you'll see the untransformed XML document with a slight change: I renamed the server copy of the stylesheet to squareAsHTML.xml, even though it's the exact same stylesheet file. As I write this, my web server's host provider ships XSLT stylesheets with a MIME type of text/html, so Mozilla treats them as HTML files. (I've suggested that they send them as text/xml.) When I give the stylesheet an extension of "xml", their server ships it with a MIME type of text/xml, so Mozilla knows that it's not HTML and uses its TransforMiiX XSLT processor to apply the stylesheet to the document and then renders the result in the browser.

As long as it's going to be rendered in a browser, you may as well take advantage of other features that modern browsers offer. My XSLT stylesheet above added a little CSS stylesheet to the rendered HTML to set the fonts of the output. By including JavaScript code with your result HTML, you can take advantage of client-side processing to add interactivity to the web pages that get created by your XSLT stylesheet.

Outputting HTML with JavaScript

The following stylesheet resembles the previous one, except that its head element has a script child element along with the title and style child elements. JavaScript code in this script element declares a function that displays a message box showing the square of the number passed to the function. If you pass it the number 3, the message box will say "the square is 9."

For each number element read from the input, instead of figuring out the square of the number, the second template rule adds a button to the form created by the first template rule. When clicked, this button calls the function declared in the script element.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<!-- squareAsHTMLJS1.xml: create an HTML document with JavaScript that
     interactively computes the square of each "number" element read from 
     the source tree. -->

  <xsl:template match="/"> <!-- Set up web page -->
    <html>
      <head>
        <title>Squares</title>
         <script language="JavaScript1.2">
           function showSquare(n) {
            alert("the square is " + n*n);
           }
        </script>
        <style> <!-- Put a little CSS in -->
           body { font-family: arial,helvetica; }
           h1   { font-size: 14pt }
           p    { font-size: 10pt}
        </style>
      </head>
      <body>
        <h1>Squares</h1>
        <p>Click a button to see the square of that number.</p>
        <form>
        <xsl:apply-templates/>
        </form>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="number">
    <p><input type="button" value=" {.} " onClick="showSquare({.})"/></p>
  </xsl:template>

</xsl:stylesheet>
    

Also in Transforming XML

Automating Stylesheet Creation

Appreciating Libxslt

Push, Pull, Next!

Seeking Equality

The Path of Control

To see this stylesheet in action, send your browser to this variation on the numbers.xml document from above. Its only difference from the original numbers.xml file is that it points to this new XSLT stylesheet. (Don't take my word for it -- do a View Source to see.) Again, the stylesheet has an extension of "xml" so that it works as well with Mozilla as it does with IE.

Putting a lot of JavaScript code inside of a script element in an XSLT template can get messy, so it's often convenient to store it in a separate file and then reference it with the script element's src attribute. This final variation on numbers.xml points to a stylesheet that does just that; it looks like the stylesheet above, but its script element has an src attribute that points to a squareAsHTMLJS2.js file. The showSquare() code is stored in squareAsHTMLJS2.js instead of being between the <script></script> tags in the XSLT stylesheet.

Keeping your JavaScript code in a separate file is cleaner, but putting it between the <script></script> tags gives you a powerful opportunity: you don't have to hardcode your JavaScript code in your XSLT stylesheet; you can write XSLT logic to generate JavaScript code based on dynamic conditions such as values in your input. Next month, we'll see how this can let you turn nested a elements in an XHTML source document into one-to-many links implemented as pop-up menus in the rendered result.


Comment on this articleHave you used XSLT to emit JavaScript-enabled HTML pages? Share your experience in our forums.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Full Threads Newest First
  • Carpet Cleaning Encino, CA 818-386-1022
    2008-11-24 17:09:13 orellytos [Reply]

    Carpet Cleaning Encino 818-386-1022
    Full Service Carpet Cleaning Mattress Cleaning, Upholstery Cleaning, Area Rug Cleaning
    We offer carpet cleaning services such as; Steam Cleaning, Dry Cleaning, green organic carpet cleaning, Fabric Lounge Suite Cleaning, Leather Lounge Suite Cleaning, Tile & Grout Cleaning, Mattress Cleaning, Wet Shmapoo Carpet Care / Water Damage Restoration, Air Duct Cleaning for: offices, homes, restaurants, clubs and hotels
    Los Angeles areas

  • How to send 2 paramters to javascript function
    2006-12-03 22:45:01 SaichandKamisetty [Reply]


    For 1 parameter i have used this code :


    javascript:showNPSData({./SC_DF_FIELD_1});


    But for sending of 2 paramters its not accepting this form
    javascript:showNPSData({./SC_DF_FIELD_1},{./SC_DF_FIELD_1})


    Can you plz help me ?

  • what about the browsers supporting the XSLT templates?
    2004-06-29 21:28:42 Navdeep [Reply]

    Which are the browsers who support fully, the XSLT templates without any extra XML parser like MSXML?
    like IE 5.5,Netscape 6 does not support XSLT. how about the new browsers. do they have builtin parsers to parse XSL?


    thanks
    Navdeep

  • what if scripts and styles are defined in external files?
    2004-04-13 04:44:08 matek994 [Reply]

    what if scripts and styles, used in the xslt-templates are located in external files?


    is this possible.


    i get problems here... having the xml-file to be transformed in one folder, and the rest, i.e. xslt-stylesheet css-stylesheet and js-document in a subdirectory, referencing these becomes difficult.


    including the hmtl tag <script src..> and <link href=..css..>, and using relative uri:s leads me into trouble. the relative uri:s are resolved based on the uri for the xml-file, and not for the xslt file...!!!!


    help!?!!


    /mats

  • xslt and javascript
    2003-03-21 01:40:19 veronique dupal [Reply]

    Hi,


    How can I use an array as a variable in an XSLT document and then send it as an parameter to a javascript function.


    Thanks in advance




  • Watch out with output escaping...
    2003-03-20 18:00:26 Frederik Willaert [Reply]

    Hello,


    A "caveat" I ran into when producing JavaScript with XSLT...


    As you may have read in the thread about "CDATA", you can simply write e.g. "<" in order to get "<" in the JavaScript output. However, it appears that this only works correctly when the output method is set to "html", either by:


    - explicitly setting the output method to "html" on the <xsl:output> element
    - making sure that the output document has <html> as its root element, and either there is no <xsl:output> element in your stylesheet, or it has the value "html" - in this case, the XSLT processor defaults to the html output method, as the XSLT spec explains.


    Either way, output escaping is only disabled for the content of the <script> and <style> tags (again, see the XSLT spec, http://www.w3.org/TR/xslt#section-HTML-Output-Method).


    If you _have_ to use the xml output method, an alternative is to use <xsl:text disable-output-escaping="yes">, but this soon gets messy.


    I've been experimenting a bit with the different possibilities (using MSXML4.0, by the way), but I still may have missed something - tell me. I should read that XSLT spec a bit more thoroughly, I guess...


    Frederik Willaert


    PS. I know this post has something to do with the CDATA thread, but I thought this could be considered as a separate topic...

  • ?
    2003-02-17 02:37:29 ard schrijvers [Reply]

    ?

  • Scripts need CDATA too
    2003-02-13 07:05:51 Taylor Cowan [Reply]

    Bob, I want to add that we need to use CDATA with larger scripts, and any non-xml text in general.
    This would cause a problem:


    <script language="JavaScript1.2">
    function showWhyWeNeedCdata {
    if ( 1 < 2 )
    alert("scripts need CDATA");
    }
    </script>


    Yours were fine, but we run across <,>, and sometimes & in scripts.


    Taylor Cowan


  • is there a way to have XSLT not check script for tags?
    2003-02-07 16:19:11 lee davis [Reply]

    E.g. I have three routines
    function Odd(){document.writeln("<tr class="RO" ... function Evn(){document.writeln("<tr class="RE" ...
    function rowEnd(){document.writeln("</tr>" ...
    which I programitcall call properly. But the XSLT complains because there are unmatched <tr> tags in the above code even though I will call the odd for half the rows, evn for half and rowend for all.
    Is there a way to tell it to not check the javascript it will produce?



  • 2003-02-07 05:47:22 ard schrijvers [Reply]



  • Performance Metrics in Internet Explorer
    2003-02-06 17:10:03 John Allen [Reply]

    Do you have any performance metrics on rendering a much larger example (1MB, 10MB, 50MB, ?) of this by using ActiveX objects to load, transform and render this versus embedding the JavaScript in the XSLT? It would would be valuable to know if pulling both the xml and xsl files into an HTML document, processing it and outputting it into a <div> is faster than the method you describe.

  • Server-side processing is better
    2003-02-05 21:47:27 Nasseam Elkarra [Reply]

    Referencing stylesheets from within XML documents is not the optimal method for transformations. This method depends on the widespread adoption of browsers supporting the XSL recommendation--something you cannot count on if you are a webmaster. By using the server's ability to detect the client's browser, you can have one XML file and apply a specific stylesheet based on the client profile. This allows the XML document on the server to be transformed using a specific stylesheet and then sent to the client as pure XHTML, WML, etc. Using the server's power to transform will also benefit slow connections and small devices. The benefits of server-side processing easily outweigh those of client-side processing. This fact should make server-side processing the preferred method for transformations and a possible candidate for a future article, no?


    Nasseam Elkarra

    http://www.myspotter.com