Back to writing

Article archive · 2006

The XSLDataGrid: XSLT Rocks Ajax

Originally at XML.com.

Locally archived May 15, 2026 so the content survives if the original host goes offline. View original

Author: Lindsey Simon Published: August 23, 2006 Source: XML.com (O'Reilly Media)

Overview

This article presents a datagrid component built with XSLT and JavaScript, designed for easy setup, strong performance, and minimal dependencies. The dynamic datagrid is an often cumbersome widget to set up.

The problem

Three common approaches to JavaScript widget creation:

Approach #1 — Server-side instantiation. PHP example:

$dg = new DataGrid();
$dg->columns = array( "field1", "field2", "field3" );
$dg->data = $data;
$dg->render();

Approach #2 — Browser-side instantiation through DOM creation. Using ActiveWidgets Grid:

var myCells = [
  ["MSFT","Microsoft Corporation", "314,571.156"],
  ["ORCL", "Oracle Corporation", "62,615.266"]
];
var myHeaders = ["Ticker", "Company Name", "Market Cap."];

var obj = new AW.UI.Grid;
obj.setCellText(myCells);
obj.setHeaderText(myHeaders);
obj.setColumnCount(3);
obj.setRowCount(2);
document.write(obj);

Approach #3 — Hybrid. Declarative XHTML serves as a base, then is enhanced. Like building a house: the declarative XHTML is the frame, while DOM additions are the siding, air conditioning, and champagne-filled hot tub.

var myGrid = new XSLDataGrid( 'renderDiv', { width: 480, height: 200, transformer:'client', debugging: true } );

Approach #1 lacks portability since it depends on the server language. Approach #2 fails when JavaScript is disabled and struggles with large datasets. Approach #3 is the chosen compromise.

In defense of the table tag

While CSS has rightly reduced reliance on tables for layout, the <table> family provides a declarative, semantic language for describing tabular data — handling cases where nested DIVs and floats grow unwieldy. With CSS disabled, pure DIV-based table presentation degrades poorly.

XSLT on XHTML

XSLT lets us decorate the DOM with well-formed markup in a powerful, flexible way. The transform results are inserted back via the container's innerHTML property — a technique known as AHAH.

From quirksmode.org's "Benchmark — W3C DOM vs. innerHTML":

innerHTML is faster than 'real' W3C DOM methods in all browsers. The W3C DOM table methods are slow to very slow, especially in Explorer.

The XSLDataGrid process

Semantic XHTML Table + XSLDataGrid.xsl → Decorated XHTML (more tags, attributes, CSS) + JavaScript (instantiation, event listeners) → Rich DataGrid UI in the render tree, with the original XML DOM kept in memory.

Dual-DOM, or, how I dealt with innerHTML

Three usage modes for the component:

  1. Fetching fully-decorated XHTML from the server each time.
  2. Fetching semantic XHTML from the server and transforming it client-side.
  3. Transforming XHTML already present on the page client-side.

For case 1, all change operations (column resize, sort, reorder) can be delegated to the server. Cases 2 and 3 require XSLT to run repeatedly, so well-formed XHTML must remain available. Internet Explorer "optimizes" innerHTML by stripping quotation marks and end tags, making round-tripping unreliable.

To work around this, on initialization the XSLDataGrid stores an XML DOM Document built from the original semantic XHTML — the "Dual-DOM" technique. For column resizing, instead of updating numerous DIVs, SPANs, THs, TDs, and COLs in the render tree, the component only changes one width attribute in the XML DOM and re-runs the XSLT.

XSLT in the browser

Both Internet Explorer and Firefox expose XSLT APIs. Manos Batsis's free Sarissa library wraps the loading of XHTML and XSL and invokes the browser's native transform method. At publication time, XSLT was not exposed to JavaScript in Safari or Konqueror, and Opera's XSLT API was not yet implemented in the XSLDataGrid.

Client-side sorting works by extracting a subset of template nodes from the XSL via DOM, then transforming the current TBODY with that subset plus parameters. The technique is limited to XSLT 1.0 datatypes — only "text" and "number." Adding "date" support via qname stylesheet templates was on the roadmap.

Benchmarks

Tests were run with the help of the Venkman profiler. Server-side tests used GNU/Linux with PHP 5.1.4; client tests used a 2GHz Pentium M running Firefox 1.5.0.6.

Rows Pre-XSLT (KB) Post-XSLT (KB) Client-side XSLT (ms) Server-side XSLT (sec)
200 17.5 29.6 156.25 0.0306
500 43.6 68.8 369.79 0.0356
1000 87.1 134 781.25 0.0860
2000 179.1 270.5 1684.38 0.2068
4000 363.1 543.5 3070.31 0.3979
8000 731.1 1089.5 6265.63 0.7861
20000 1885.1 2787.5 16695.31 4.0880

Conclusions

The principal benefit of XSLT for a JavaScript widget is flexibility at instantiation time. Since most Ajax developers already work with a server-side stack, being able to skip the client-side decoration step boosts performance — though at a bandwidth cost. Projects often involve a mix of large dynamic datagrids (best served from the server) and smaller hand-coded tables. The XSLT-based design lets developers choose either client or server transformation while preserving a consistent look and feel.

Required libraries (historical)


Originally © 1998–2008 O'Reilly Media, Inc.