XSL Considered Harmful

May 20, 1999

Michael Leventhal

Declaration of War

XML VERSION: An XML Version of this article is available here. Two weeks ago published an article by G. Ken Holman, What's the Big Deal With XSL?, in which the author expressed his "perplexity about the perceived controversy over XSL." I expressed my surprise and disappointment to that one point of view in this "perceived controversy" had been given such a full airing while nothing had been heard from the other side. I asked for equal time and I was given it.

I am going to start out with a brief and perhaps stark statement on the subject, my "declaration of war". It is high time we get to the heart of the matter.

XSL, a "sometime in the future" technology, full of beautiful (if vague) prognostications about its "power" and "richness", offers no useful improvement in capability over current and implemented full W3C Recommendations for stylesheets and transformation.

XSL has no role to play in the evolution of web technology into the "new desktop" as it does not support interactive documents.

XSL is a great danger to a major objective of XML, the inclusion of semantic information in Web pages, as it replaces XML elements annotated with formatting information by XSL formatting objects.

XSL is the most hideous and unwieldy language imaginable and stands absolutely no chance of acceptance by the web community.

XSL advocacy has blurred the focus of the W3C, by introducing competing standards for styling and transformation, and set back by at least two years the goal of vendor-independent, semantically rich "open information highway", by undermining support for existing standards such as CSS and the DOM.

This is really all I have to say, but if any one of these points is true, that is a damning case against XSL. I have invited and continue to invite, in good faith and with an open mind, XSL advocates to counter these arguments.

In the remainder of this article I will elaborate on these five fatal flaws of XSL and present an application which will give you the chance to directly compare XSL to the transformation and styling technologies supported by current W3C Recommendations. But first, The Challenge:

The Challenge

Anything XSL can do in the Web environment, I can do better using technologies supported by current W3C Recommendations.

Of course, what is "meaningful" in the Web environment is open to a variety of interpretations. Therefore, the subject of the challenge should be one that the XSL camp and I agree is meaningful.

I am also ready to make this bet a little bit more than an academic exercise. If I lose, I will pledge that I, and my crack mozilla development team, will assist in implementing XSL in the mozilla open source project. If my opponents lose they will agree to desist from XSL advocacy, vote against an XSL Recommendation if they are members of the W3C, and will join me in calling for full, flawless, and unequivocal vendor support of CSS1 and CSS2, DOM Level 1, and XML 1.0 as the very first and top priority of the web community.

Next we explore the five fatal flaws of XSL.

XSL Has Nothing New for the Web

The major justification for XSL is that it will support better specification of printed page layout than is now possible with CSS. In other words, XSL has little or no relevance for virtually all types of documents on the web today. The web is not about paper documents. Page composition will not even occur on the Web as it is a notoriously computationally-intensive process. There are many solutions to page composition available today; the sole advantage of XSL would be that it allows the handful of people that design page layout processes to use the same language both for producing printed pages and for producing web pages. However, the nature of the layout discipline is dramatically different. Frankly, people that design page layout processes will have no difficulty creating a CSS stylesheet for the Web and an DSSSL stylesheet for paper, one of the solutions which is already in place today.

A more important point is that XSL, as a web page style language, is an enormous unknown in terms of processing efficiency. It is relatively straightforward to write down on paper a specification that not only slices and dices but also cooks the turkey and sends out your dinner invitations. But ... will it work, can it be cleanly implemented and maintained, how much memory is it going to use, how fast will it be? These things are not known for XSL and good professional opinion says it is going to be a dog. CSS is trim and has been shown to be efficient.

Other than printed page layout, XSL has very little to add to CSS formatting capabilities, perhaps a point or two which would justify a few modest additions to the next revision of CSS, but surely not an entirely new language. Improved selectors on the element hierarchy and attribute values are the major items in this area.

The fact is that the powerful styling capabilities of CSS, including hierarchical and element selectors, floating, absolute and relative positioning, generated content, counters and autonumbering, and table formatting, have not been experienced either by the general web community or the XML community. I know this because some of these features have only appeared in the mozilla browsers as recently as two weeks ago. We just now have the ability see what CSS can do - and it is going to change the world view of a whole lot of people. May I be so bold as to ask how much real world experience with CSS2 the working group designing XSL has? Is this not a reasonable prerequisite for designing a new language which better addresses the needs of web developers?

XSL is not, of course, just a style language. It also supports tree transformations, the mantra of XSL community having been that transformation and styling were inseparable processes. In fact, they are not inseparable and even some XSL advocates have begun to call for a clean separation between the proposed transformation language and the formatting language. The fact that interests us here however is that there already exists a way to do tree transformation that adheres to a W3C Recommendation today. It is called the Document Object Model (DOM) and can be used in browsers now through its binding to JavaScript and other languages (Java, C++, Perl, Python).

When compared to the DOM+CSS, XSL does not solve any Web-related problems that the current W3C Recommendations do not adequately handle. What is the Big Deal indeed?

XSL Does Not Support Interactive Web Documents

With HTML forms included through the HTML namespace, but without CGI, and definitely without XSL, we at CITEC are building the following Web browser-based semantically rich XML applications:

Online Books/Manuals with Hypertext TOCs and structured search
Web browser designed for a car with simulated feeds to diagnostic and maintenance systems
Manages hyperlinks in document collections, providing interface, maintenance, editing and visualization of a link database and links targets and sources in documents
Simulated stock reporting feed, shown in this article
Interface to email system
Interactive Electronic Technical Manual Interface with special safety features
Allows insertion of annotations into documents
WindowsHelp-like system
Does slide shows
DTD-driven XML editor

I showed some of these applications at the XML Europe conference and also delivered my now-standard denunciation of the "XSL conspiracy". The speaker who had the misfortune to follow me was a very knowledgeable gentleman whom I respect very much, Neil Bradley (author of The Concise SGML Companion and The XML Companion), and the topic he had the misfortune to cover was, of course, XSL. And he began by saying that, of course, he would never attempt to create the applications he had just seen with XSL because "XSL is not for interactive documents".

Is there really anything more to say? If XSL is no good for interactive documents what do I need XSL for? Is there anyone out there that is not interested in enabling interactive behavior in a clean, structured, standard, and maintainable way in their web documents? Isn't that what XML on the Web is for, to enable such applications to be built using semantic information from element names, attributes and the document structure? This is what we thought and this is what we have been doing. We think our 'Zillas are the proof that XML on the Web does everything XML on the Web was promised to do. And we do it with XML, CSS, and the DOM and really cannot understand why anyone could, would or should give a damn about XSL.

The whole XSL process, described admirably enough in Mr. Holman's paper, is a static process. Interactive processes are designed around events which have event handlers associated with them. An event could, in principle, occur on any XML element (in fact we have done exactly this in many of our 'Zilla applications) and can invoke a myriad of behaviors which most often involve the modification of some element styling or perhaps the update of a element value. Occasionally, a little reordering of some part of one or more document trees takes place. Much less commonly, all or a large portion of the document is reordered, as in an application which updates a sorted table. The CSS model of attaching formatting to the elements is perfectly adapted to handling events which cause stylistic changes, and the DOM model is very efficient for updates to the document tree contents and local reordering. It is adequate for global reordering. In addition, the document trees often reside in different frames or windows and one must have communication between them. JavaScript provides these kinds of facilities as it is an environment native to the browser environment. When an event occurs you typically want to know what element it occurred on, what its name and attributes are, and most often you will be doing things that will effect its immediate children or parent. This is all elementary stuff if you're using the DOM and JavaScript. Finally, it all has to be very fast.

The XSL folks seem to be about a million miles from this, proposing a horse-and-buggy model in laser-guided precision missile world.

Semantic Information Threatened by XSL

I can understand why overworked undergraduates think FONT is cool, but I'm very disappointed when a group of highly skilled adults tell kids to stop playing, form a committee - and then come out with a set of supercharged FONT tags.

Håkon Lie on XSL Formatting Objects, xsl-list, 28 April 1999

Dear Mr. Lie (co-inventor of CSS) has penetrated once again to the essence of a matter ... and in his inimitable style. If I could only win friends and influence people like that! I highly recommended that you go and get the full story from his paper " Formatting Objects Considered Harmful". A short version of the story is this: XSL proposes the existence of something called a formatting object, XML elements which indeed resemble what Mr. Lie calls a supercharged FONT tag. It is the final result of an XSL transformation which is sent to the rendering engine. If the rendering engine reads formatting objects directly, all the semantic information in the original information may be lost. This is exactly the information we get through element events and the DOM to make all of our 'Zilla applications work. XSL, in this scenario, would destroy XML on the Web.

Among the solutions to this problem is stipulating in the standard that formatting objects must preserve a mapping back to the original XML element. Technically not very elegant and probably unenforcable.

Another solution is to legislate that formatting objects not be allowed to ever physically exist as XML. Not bloody likely, but there is a logical candidate to replace XML formatting objects: CSS! One must ask why don't we just forget about formatting objects and just use CSS in the first place?

XSL is an Ugly, Difficult Language

XSL is DSSSL in sheep's clothing, an SGML transformation and formatting language that an ISO committee worked on for eight years, producing finally a language specification and an utterly heroic and breathtaking but incomplete implementation by James Clark that years of real world experience has shown to be incomprehensible and unusable to nearly everyone in the document transformation and formatting business. XSL is DSSSL, it is 100% DSSSL concepts and processing model, with some syntax changes and some attempt to merge with CSS.

I can't back up my assertion with numbers but I personally have written hundreds of transformation applications and have used nearly every tool and language in this area, DSSSL included. It is truly a tiny handful of people who have been able to master DSSSL concepts and fewer still that have been able to get it to work on a real world project. I am one of those people and I happened to have the opportunity to write such a real world application in both DSSSL and one of the popular commercial transformation languages, Balise. The DSSSL implementation took me two full weeks, Balise two days. I am qualified to give an expert opinion in this area and my opinion is that DSSSL and XSL are hard!

This is important because of the following assertion, which comes repeatedly from the XSL camp: XSL will make life easier for web developers because they will not have to write programs to perform complex document transformations. You see, XSL is not a "programming" language but a "declarative" language. XSL declarations don't do anything, they describe the state of the transformed document in relation to the original document.

It is a fascinating and lovely idea. The problem is that real-world transformations are hard, full of tricky stuff and zillions of little details such that an overly simple model of how to do or declare it quickly breaks down and becomes infinitely harder than the programming model with its many features for managing complex tasks.

I know I am not going to convince anyone that doesn't want to program to become a programmer, but I hope to convince at least some of you that we are very close to defining the ideal intersection between the talents of the programmer, the data/document designer, and the style expert with XML, CSS and the DOM. XML puts control of the design process solidly back in the hands of the subject matter expert who designs the document types. CSS allows the designer to isolate the style issues cleanly . The DOM provides the programmer with an orderly approach to interactive application programming (including transformation) and prevents the the web document from becoming an incomprehensible mixture of code and data. XSL is a big step back, it mixes everything up again and puts everything in the hands of the few people who can understand this weird declaration thing which is simultaneously both past and future and in which nothing really ever "happens".

I mentioned the support in programming languages for managing complex tasks. I am talking about things that engineering scientists have studied and developed over many years of research into program design. Things like program modules, argument passing, scope, state, basic and complex data structures, naming conventions, debugging techniques. These are admittedly unfamiliar to people not trained to write programs and they may seem like an unnecessary complication. They are not: the proper use of such techniques will ensure that your transformations are readable and maintainable to people who can read and maintain programs and that the results will be reliable.

I'd like to offer another little challenge to those that are still unconvinced - go and read the XSL script used to produce Mr. Holman's article ( Can you understand it? Is the fact that it is a declaration really making life any easier for me? He is doing basically really simple transformations, just gathering some element data to stick in tables at the end of the document - I gave the same assignment to a junior programmer on my team for him to learn the DOM. But it is enough to push XSL to the wall.

XSL has Set Back the Web at least 2 Years

When I have criticized Microsoft for the lack of complete and correct CSS support in IE5, I have found that many are quick to class me among the irrational Microsoft bashers. In fact I am keenly interested in seeing Microsoft create a browser which adheres to Web standards. I want to see this because I believe that to a significant extent it is the character of our new information-based civilization which is at stake. I also happen to believe that we will sell many more of our 'Zillas if the technology we use is also supported by Microsoft and by other browser vendors. Finally, I think that the vendors can be persuaded that it is in their interest to support web standards if consistent pressure is applied to them from the marketplace and from those people who are the catalysts for new technological developments.

Today there is one and only one W3C Recommendation for the formatting of XML documents on the Web, CSS. Today there is one and only one W3C Recommendation for transformation and manipulation of XML documents, DOM. This year we could have had semantic markup on the web, in the major browsers, with support for XML 1.0, CSS and the DOM. This did not happen and I am sorry to say that XSL advocates that did not clearly articulate their support for current Web Recommendations contributed heavily to that state of affairs.

I think it is clear to all that the early implementation of XSL by Microsoft was a disaster. As predicted, the next version of the W3C XSL draft created two XSLs, the W3C's and Microsoft's. But more important than this is the fact that XSL has been a major marketing coup for Microsoft in enabling them to "hide" their deficient implementations of web Recommendations and to force the entire marketplace to postpone XML implementations for another couple of years while we wait for common standards that work in the all the major vendor's products.

The corrective action at this point is to do what we as a community should have done six months ago, to insist on full implementation of CSS, the DOM, and XML. If we clearly articulate this message now we may have XML on the Web in one year instead of two. If we wait for XSL to either flop or succeed it will definitely be two and if it does flop perhaps it will be three. There are also issues far more basic and critical than XSL which the W3C should be addressing with greater attention and priority. These include linking, row and column spanning in CSS-specified XML tables, and inclusion of scripts in XML files possibly followed by query and schema issues. Our first order of business is to create a workable and standard XML environment for the Web. XSL, a standard designed to improve the layout composition of printed documents, should not be in our first order of business.

The second part of this article consists of a comparison of the well-known Microsoft stock-sorting XSL and an enhanced application which uses the DOM and CSS instead of XSL.


XSL vs. the DOM+CSS toe-to-toe

In this section we will compare the effectiveness of XSL to the DOM for transforming XML documents and we'll show where the DOM+CSS approach goes way beyond XSL in enabling the scripting of dynamic, interactive behavior in truly Web-oriented XML applications.

XML VERSION: An XML Version of this article is available here. The original XSL application was developed by Microsoft. It can be run (on IE5 browsers) at A zip file of all the necessary files is available at According to Jonathan Marsh, Program Manager, XSL at Microsoft, the example currently at the above URLs expands on the application described in this article with the addition of data-typed sorting, number formatting, and simple data-driven formatting changes. The author did not have a chance to look at these changes before we went to press.

The XSL application can only be run in IE5. It is not W3C Recommendation compliant as XSL is not currently a Recommendation of the W3C. I do not know if this application adheres to the most recent revision of the XSL Working Draft but judging from the comments in Mr. Holman's paper about "msxsl" I gather that this is not likely.

The DOM+CSS application is compliant with current W3C Recommendations and can be run in any browser which supports them. At this moment that includes at least the Gecko builds at and DocZilla at

The XSL Stock Sorter

This application sorts the rows of a table based on values in any individual column by clicking on the header of the column. The sort is straight ASCII (z comes before A) string sort and it does not handle numeric or other types of values.

The file downloaded to the browser is XML. XSL is used to convert the XML into an HTML table. Each table header has a nested Div tag with an onClick event to invoke the XSL sort, passing the name of the field to be sorted to the routine. The entire document is regenerated in HTML each time the table is sorted.

By the way, the time and date is hard-coded into the demo. I may as well give away now that the JavaScript scripting environment will of course give us many date operations including tricky date conversions (humans like to see dates and times displayed in a variety of ways and computers also have their own ideas about how to represent a date) as well as timer operations which will allow us to trigger our stock updates from the client-side at whatever interval the user desires.

The contents of "sort-stocks.xsl", referenced in the "portfolio.xsl" script, trigger the transformation of the document, I think. It's complicated!

DOM Stock Sorter - Functionality

The functionality is similar to the XSL Stock Sorter - but with some important differences. Type-specific and directional sorting has been implemented, and the default values are actually encoded in the column header (One could imagine being able to change properties of the sort from controls in the page.) There is an XML column header instead of the column headings hard-coded in the script found in the XSL application. Here is a snippet of data showing the header and a row of stock information:

<?xml version="1.0"?>

<?xml-stylesheet href="stuff.css" type="text/css"?>




    <colhead field="string/g" direct="asc">Symbol</colhead>

    <colhead field="string/g" direct="asc">Name</colhead>

    <colhead field="curr" direct="desc">Price</colhead>

    <colhead field="num" direct="desc">Change</colhead>

    <colhead field="units" direct="desc">%Change</colhead>

    <colhead field="units" direct="desc">Volume</colhead>






    <name>Love Corp</name>






The colhead field attribute allows one to specify case-insensitive string sorting (/g - z comes after A), currency, numeric, and numeric with a units symbol sorts and the direct attribute states whether the sort should be ascending or descending.

The table is formatted in XML using CSS2 table display properties. Hey, you don't need XSL to create HTML tables if your browser is CSS2 compliant! It looks quite good, if I say so myself:

Screen Shot of the CITEC Stock Sorter - click for a larger version

The stylesheet for this application is shown below:



    display: table;

    margin-top: 0.5em;

    margin-bottom: 0.5em;

    margin-left: 0.5em;


symbol, name, price, change, percent, volume 


    display: table-cell;

    font-family: Arial, Helvetica, sans-serif;

    font-size: x-small;

    line-height: 1.2;

    vertical-align: top;

    padding-left: 0.2em;

    padding-right: 0.1em;

    padding-top: 0.1em;

    border-bottom: 1px solid navy;




    cursor: pointer;

    display: table-cell;

    font-family: Arial, Helvetica, sans-serif;

    font-weight: bolder;

    font-size: small;

    text-align: center;

    line-height: 1.2;

    vertical-align: top;

    background: #CCC;

    color: black;

    padding-left: 0.2em;

    padding-right: 0.2em;

    padding-bottom: 0.05em;

    border: 2px inset black;



stockhead stock symbol, 

stockhead stock name


    text-align: left;









    padding-right: 0.4em;


stock, headrow


    display: table-row;




    display: table-header-group;




    display: table-row-group;


We use the DOM to traverse the elements of the column header and to set an onMouseDown event sort handler for each one. We use DOM operations to also get attribute information to guide the sort and to actually handle the mechanics of rearranging the node.

Of course, we have no need to regenerate the entire document. Another very important point about the DOM approach is that the code is all totally generic - it will work on any table having matrix (no spanned rows or colums) structure and headers.

DOM Stock Sorter - Code

In the main routine four global variables must be declared which are specific to the table markup. An array is created which will hold the table cells and makeSortableTable is called. That is all that is needed to make the table sortable by clicking on column headings. The four global variable which must be declared contain the name of the column header elements, the name of the row container elements and the attribute names used to identify the direction of the sort and the field type.

var gHeaderRowCellGI            = "COLHEAD";

var gRowCellGI                  = "STOCK";

var gSortDirectionAttributeName = "DIRECT";

var gFieldTypeAttributeName     = "FIELD";

var gTableCells = new Array();


It may be of interest to note that this information could be passed to the application by means of architectural forms, a technique by which any element or attribute can be associated with an abstract element type such as COLHEAD, STOCK or attribute type such as DIRECT or FIELD and thereby entirely avoiding any markup-specific code. (If, of course, the browser has the ability to understand architectural forms.)

Before we go on, I would like to emphasize again - from this point on you are looking at totally generic library functions which can be used with many different XML files and applications - they are library or utility functions. The markup-specific part of our code was the four declarations shown above. An extremely important characteristic of procedural programming languages is that they allow and even strongly encourage reusable module construction.

function makeSortableTable(rowCellGI)


We will set up sort event handlers on the cell headers. Compare this to the XSL application's technique of using an onClick attribute in the generated markup. This technique allows one or more event handlers to be set on any XML element at any point in the processing without requiring any special attributes in the markup.


We get all the row elements and store them in global array. Then we call putDOMNodeIntoSortTable to extract the cell elements in the rows and store them in a two dimensional array ready for sorting.

  var celllist = document.getElementsByTagName(rowCellGI);


  for (var i=0; i < celllist.length; i++) {

    gTableCells[i] = celllist[i];




function putDOMNodesIntoSortTable(nodes)


  var i, j;

  var ncount = nodes.length; 

  for (i = 0; i < ncount; i++) {

    var node = nodes[i];

    var childNodes = node.childNodes;

    var ccount = childNodes.length;


    for (j = 0; j < ccount; j++) {

      var child = childNodes[j];

      node[j] = child.firstChild.nodeValue;      




Here is where we do the actual setting of events on column headers discussed above. We get the column headers by the element name specified in our declaration and set an onmousedown event handler called sortOnColumn on each header cell returned in the headerCells array.

function SetSortOnCellHeaderEvents() {

    var headerCells = document.getElementsByTagName(gHeaderRowCellGI);

    for(var i=0; i<headerCells.length;i++) {

        headerCells[i].onmousedown = sortOnColumn;



sortOnColumn is the event handler invoked when the user clicks on a header cell. First it must get the fieldtype and direction attributes from the column header to invoke the proper sorting for the column. Actually we just iterate over the column header cells until we find a node which matches the node on which the event was triggered. Once that node is found all we need to do is invoke the low level sort routine, passing the column number, fieldtype, and direction as arguments.

function sortOnColumn(e) {

      // node is text, parent is headercell, parentparent is 

      // container for header cols

    var node =;

    for (i=0; i<; i++)


      if (node == {

        var fieldtype = "";

        var direction = "";   

        for (var j=0; j<node.attributes.length; j++) {

          var currAttr = node.attributes[j];

          if (currAttr.nodeName == gFieldTypeAttributeName) {

            fieldtype = currAttr.nodeValue;


          else if (currAttr.nodeName == gSortDirectionAttributeName) {

            direction = currAttr.nodeValue;






      else {

        node = node.nextSibling;




This is a really bad sort routine so I should be careful here to blame the folks I stole it from: it was lifted from one of Netscape's demos (my colleague Heikki says it would be good for me to try to be nice from time to time and suggests that I might better say "the routine is simple and more robust things would be used in real-life applications"). I added the nice bits with handling the fieldtypes and direction. The sort is just a bubble sort, the more unsorted the table is the more swapping of nodes takes place. Comparison between nodes is done with compare function which takes into account the fieldtype and direction.

function sort(collection, key, fieldtype, direction)


  var i, j;

  var count = collection.length;

  var parent, child;


  for (i = count-1; i <= 0; i--) {

    for (j = 1; j <= i; j++) {

      if (compare(collection[j-1][key], collection[j][key],

          fieldtype, direction)) {    

         // Move the item both in the local array and

         // in the tree

         child = collection[j];

         parent = child.parentNode;

         collection[j] = collection[j-1];

         collection[j-1] = child;


         parent.insertBefore(child, collection[j]);





compare makes use of JavaScript's decent regular expression, string, and math classes, quite necessary even in a relatively small application such as this one. Let's not kid ourselves, without all of this XSL is out of the running for real world applications and with it XSL will have reinvented the wheel - except that it will be square.

function compare(value1, value2, fieldtype, direction) {

  var str;

  if (fieldtype.toUpperCase() == "STRING/G") {




  else if (fieldtype.toUpperCase() == "CURR") {

    var str = value1.match(/\$\s*(\d*\.\d*)/);

    value1 = RegExp.$1 * 1.000;

    var str = value2.match(/\$\s*(\d*\.\d*)/);

    value2 = RegExp.$1 * 1.000;     


  else if (fieldtype.toUpperCase() == "NUM") {

    value1 = value1 * 1.000;

    value2 = value2 * 1.000;

    value1 = Math.abs(value1);

    value2 = Math.abs(value2);  


  else if (fieldtype.toUpperCase() == "UNITS") {

    var str = value1.match(/((+|-)?\d*\.\d*)/);

    value1 = RegExp.$1 * 1.000;

    var str = value2.match(/((+|-)?\d*\.\d*)/);

    value2 = RegExp.$1 * 1.000; 

    value1 = Math.abs(value1);

    value2 = Math.abs(value2);  



  if (direction.toUpperCase() == "DESC") {

    return (value1 < value2);


  else {

    return (value1 > value2);




The DOM implementation of the Stock Sorter takes advantage of modular programming techniques to create an application which is generic and organized. The functionality of the application is easily extended to handle a variety of sort field types thanks to the depth of the JavaScript language. Interactivity through events adds the possibility of interesting dynamic behavior through reading the element generic identifiers and attributes directly from the CSS formatted XML. Effected nodes in transformations are manipulated directly in memory rather than reprocessing the entire document. W3C-compliant CSS allows XML markup which is not specifically table or layout oriented to be handled as a table. Numerous JavaScript library functions for date handling, timers, string manipulation, and math aid us to get exactly the results we want.

In fact, we have only lightly touched on the capabilities of the DOM and CSS-compliant browser in this application which already greatly exceeds the set of capabilities that can be achieved with XSL.