by Bill Schneider (bschneid@arsdigita.com)
Submitted on: 2001-06-05
ArsDigita : ArsDigita Systems Journal : One article
XSLT ("eXtensible Stylesheet Language Transformations") is a powerful,
comprehensive language for performing transformations on XML. It is an
increasingly popular technology for content-presentation separation in dynamic
web pages; the content for a web page is structured into an XML document, and
XSLT is applied to this document to produce an XML output for display in an
end-user device. This XML output can be XHTML, WML, VXML, or any other
XML-based format. Since there are standard Java APIs for XML parsing and transformations, an
application that uses XSLT can be written independently of the specific XSLT
engine used. The XSLT engine can then be swapped later for one from a
different vendor, without modifying the application. Since XML and XSLT are just another one of many mechanisms that can be used
for decoupling dynamic content from its HTML presentation in a Web
application, it is worth comparing it to other systems that strive to provide
the same separation. The other systems discussed here excel at either
providing computational power to presentation logic, or maintaining a strong
wall of content-presentation separation; XSLT accomplishes both. Also, XSLT
surpasses other presentation systems where it is desirable to easily change
the presentation of page components on a site-wide basis, to accomodate a
co-branded subsite or a new output type like WML. In the early days of server-side Web programming, people would write CGI
scripts to directly generate HTML output as string literals. Later, Java
servlets followed this model. People soon grew tired of generating complex
HTML literals in servlet code with lots of As a result, Sun introduced Java Server Pages (JSPs), which let you mix
Java code and write HTML output as HTML, interpolating values from Java
variables or method calls. JSP is functionally similar to Microsoft Active
Server Pages (ASP), though ASP predates JSP, and they are based on a different
set of technologies. JSPs are translated to servlets on demand, and execute as
such. Both make it possible to write server-side programs that look mostly
like regular HTML ("hello world" is a legal JSP) but with dynamic value
computation and substitution. JSP is susceptible to writing confusing pages that inextricably mix
business logic and presentation logic, so beans and JSP custom tags were
introduced to facilitate moving code out of JSPs and into Java classes that
could be reused over many JSPs. (Similar mechanisms for moving reusable code
out of pages and into objects exist in Microsoft ASP.) The resulting design
pattern is known as "Model 1." The later "Model 2" pattern is similar, except
that the incoming request is handled instead by a servlet that maintains
common application state across all pages (user authentication, authorization,
etc.), and then dispatches to a JSP. There are two major pitfalls with JSP. First, with the full power of Java
available inside a JSP, there is no way to enforce the Model 1 or Model 2
convention of confining application logic to Java classes outside the JSP.
Second, modifying even simple presentation logic inside a JSP (e.g., "if
status code is 'failure', color it red") often requires significant
understanding of Java's type system. For example, objects retrieved from
generic containers are usually just As a result of JSP's shortcomings, there are several JSP-like presentation
systems, like the open-source Velocity (http://jakarta.apache.org/velocity)
and FreeMarker (http://freemarker.sourceforge.net),
for building dynamic web presentation in Java. These systems provide a
simplified templating language, which is just HTML plus some scripting
elements for performing limited display logic: looping over multi-row table
data, substituting dynamic values, etc. An environment containing name-value
bindings is filled prior to the output-generation stage. This hides a lot of
the details of Java expressions and type casting from template editors, but
the types of expressions and computations that can be performed may be
limited. These systems use an architecture similar to Model 2; a request dispatcher
servlet responds to an incoming request by dispatching to another servlet
which performs application logic, and fills a data structure (usually a
The major disadvantage to this type of presentation system is the
limitations of the scripting language. To allow for HTML writers to include
conditional presentation logic (e.g., "alternate table background color with
every other row"), some sort of expression syntax is necessary. But there is a
constant tension between providing expressive power and keeping things simple;
this type of presentation system is not intended to replace a full-featured
programming language like Java, and so the expressive power of such systems
are limited. For example, while it may be possible to alternate table row
colors for even/odd numbered rows, it may not be possible to alter color using
a more complex arithmetic expression computed in the template itself. Another shortcoming of presentation systems like Velocity is the difficulty
of decomposing a page's presentation into components, to maintain a consistent
look-and-feel for a component across an entire site. Usually this style of
presentation system has a mechanism for including a template inside another
template, which can be used to make templated components; but then the
template for the component must be explicitly included inside all pages on
which the component appears. If an enterprise system is already using XML documents to represent data
for interchange with other systems, then XSLT allows you to use the same XML
document for dynamic HTML generation. Once the content you want displayed on a
web page is specified by its logical structure as an XML document, you
transform that document with XSLT into some other markup that can be displayed
on the user's device. This architecture allows you to generate the same
structured data as an XML document, using interchangeable XSLT rules to
generate different output types depending on whether you ultimately want
XHTML, WML, VoiceXML, etc. One usage pattern for incorporating XSLT as a
templating system for Java-based Web applications is described in the
following diagram:
However, it is possible to use XSLT in a simplified way (see http://www.xfront.com/rescuing-xslt.html);
using XSLT as a per-page templating system like Velocity sacrifices some of
the site-wide styling power of XSLT but makes for a good introduction to XSLT.
Compare the following two code examples:
Also, the main difference is that in the XSLT version, you can decouple the
rule for rendering an individual list item into a separate template rule and
invoke it with Another potential disadvatange of XSLT is performance. Because an XML
document is a more elaborate data structure than a simple name-value mapping,
it necessarily will take more memory. And, since stylesheets themselves are
XML documents, they need to be parsed as such, which takes time; or have their
parse trees stored in memory, where they could take more space than a simple
HTML-with-substitution template. Also, because the final output is specified non-positionally in XSLT,
computing the final XHTML output can take longer to compute than a simpler
templating system, where the order of literal HTML text in the template is the
same as the order of literal text in the output. There's much that can be done to mitigate concerns about performance and
scalability of an XSLT-based presentation system, though.
A page script is something like a JSP or ASP, where the logic
performed on a URL request is defined inside a file in the file system, and
the logic is mapped to a particular URL by the virtue of its pathname. The
most important characteristic of page scripting is that changes to the file,
as well as additions of new files or removals of old files, take effect
immediately when the URL is next requested, with no additional explicit action
(e.g., recompilation) required.
Although XSLT templates are not necessarily written on a per-URL basis, but
are instead written on a per-element basis, they are still useful in page
scripting environments. If we have a page.jsp page script and a page.xsl
stylesheet, the template rules contained in page.xsl stylesheet can be
combined transparently with global styling rules, so that page.xsl only must
contain a set of per-URL overrides.
Any ACS based-system is organized as a series of applications; each
application type can have one or more instances which are used to
scope the content for a particular applicatation. This allows us to have a
single news application, for example, but with different isolate sets of news
articles displayed through different URLs. Application instances are
mounted on site nodes, which are just URL stubs in the
site-wide URL tree. So when you request a URL, that URL is within a particular
site node, which is associated with a package instance, which is associated
with an application type (the code base to use) and a unique identifier for
isolating content within that package.
The requested URL resolves further to perform a specific action within the
package and display a response page to the user. Each component in the
response page generates a piece of an XML document. XSLT renders the complete
document, with contributions from all page components, into the proper output
format for the user's client (usually XHTML) by XSLT.
We associate XSLT stylesheets with package types, so any given ACS
application defines a stylesheet with all the necessary rules for rendering
the XML it generates. We also associate XSLT stylesheets with site nodes, so
that for any particular subsite, we can override the default rules for the
package. This is useful for co-branding and other localized look-and-feel
changes.
The effective stylesheet for a request is dynamically composed from a
series of stylesheets; the composed effective stylesheet can then be cached
for future requests. When a request comes in for a particular site node, we
build a stylesheet using the stylesheet associated with that site node and
all of its ancestors in the site map. Then we incorporate the
stylesheets for all relevant package defaults. (Remember, these rules don't
generate any output unless some piece of the generated content triggers them.)
The site-node specific rules will take precedence over the package defaults.
Now, if we want to embed the list of press releases as a component inside a
page in a different application, we don't have to touch the XSLT stylesheets
or their assocations. ACS always makes all packages' registered
default stylesheets available to all applications, all the time. If the XML
document generated for a page request contains a
Let's turn to co-branded subsites now. Suppose we have two URLs on our web
site, To make this stylesheet take effect for the
The new stylesheet for press releases is in effect throughout the
entire co-branded subsite. So if a press-release list is embedded
inside a page outside of the News application, the co-branded stylesheet still
applies. The process for swapping stylesheet rules based on locale or output type
(e.g., WML instead of HTML) is similar.
Nothing in the above example couldn't be done with some other web
presentation system like JSP or Velocity. XSLT is more powerful, though, for a
number of reasons:
On the other hand, XSLT can be difficult to learn and, while early results
at ArsDigita have been promising, there are still some lingering concerns
about performance and usability. Although XSLT may make it more difficult to
build a simple web application's presentation layer, it makes the presentation
layer for a complex web application not much more difficult than that for a
simple application. Using XML for an intermediate data-representation stage is
also promising because it opens doors for interoperability with other
enterprise systems. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries
Performance was also abysmal (well acceptable for moderate number of users) (with XALAN) - even when using caching of results. Slightly better with SAXON or XALAN Transformers we tried later. Nevertheless, slow as hell when we contrast it with an ASP application or a template engine like Velocity (which can be integrated to work with DreamWeaver for example). This all depends on the style of the shop. More IT-oriented and XSLT is very seducing, more design-oriented and XSLT is a nightmare. A point of note: you need to be able to understand the templates after the project has been released for maintenance tasks... not always that easy given the 'super-neat' syntax of XSL. Anyway the code was 1000 times cleaner than with a JSP application. A thing I see is better in using Velocity templates than XSL ones is that in Velocity you can pass complete Java objects directly to the template, avoiding the pain of putting the data into an intermediate XML structure which gets massaged by the XSLT processor. Even more, you can call 'set' methods from the template and get the results back into the java objects with no fuss -- try this with XSLT ! (You can go even further since WebMacro uses introspection [you drop your session object in the context and all session objects are available - how cool!] The best approach I can think of is to combine the two: Use Velocity-like templates for containers and easy components and create a #XSLT-process directive in the template language for embedding XML elements. I think WebMacro does it so you may be able to pick the directive from WebMacro and plug it into your Velocity codebase. FreeMaker may have it, I don't know. This will allow for ease of use for the designers for 80% of the design and require a developer for the 20% of complex stuff (compare this to tying a programmer to tasks he doesn't excel at [graphics and looks] for 100% of his time). This is peopleware but this is how things move forward. Another issue we had was that XSL has no real variables, you bind a value to a variable, it's for its scope only (a page). So, in a for each, you cannot have a variable incremented (like do a sum in a for - okay it can be done with a xpath and some aspirins). So, what we did is to output Javascript which in turn computed stuff. Not clean! Don't tell me that it would be possible with a recursive template - try to explain this to a designer! xsl-script was in a W3C draft (like Microsoft implemented) was useful for the above but is not there in XALAN and current spec. Comments welcome!
Last updated: 2001-06-05
A brief introduction to XSLT
XAlphabetSoup: Making sense of the standards
Node object, which represents an
element or attribute; a Document is the top-level object
that represents an entire XML document.
DocumentHandler when elements or character blocks start
or end. DOM parsers are often implemented using a SAX parser, building
the DOM tree in memory in response to SAX callbacks.
Other systems for content-presentation separation in Web applications
JSP
out.println()
statements, and it didn't take long for programmers to realize that it was
difficult for graphic designers to modify the color scheme, layout, etc. of
web pages because an edit to the HTML required editing and recompiling Java
code.Objects and need to be
type-casted to their actual (runtime) types before they can be used in
comparisons; also, primitives like ints and booleans
often have to be unwrapped from their object counterparts Integer
and Boolean.Simplified web presentation systems: Velocity, FreeMarker, etc.
java.util.Map or some variant) with a set of name-value mappings.
Then the request is dispatched to the templating engine, which processes the
template using the dynamic value map for variable subsitutions and logic.Using XSLT in a Web system
On a different axis, XML gained popularity
as a standard for representing the data in enterprise systems to deal with the
limitations of HTML. HTML is a mismash of tags to represent logical units of a
document, like <p>, <h2>, and <li>; and tags that denote
pure markup, like <em> and <strong>. There is no way to denote
logical units of a document in HTML without implying a certain look-and-feel
in a web browser, though; more on this can be found in Chapter 5 of Philip and
Alex's Guide to Web Publishing.

Document object, which can then be transformed
directly by XSLT without being parsed first.
Advantages of XSLT
XSLT has several advantages over other Web
templating systems:
xsl:apply-templates is driven by the XML input, and does not
necessarily need the name of a specific template to apply.
Disadvantages of using XSLT--and overcoming them
Usability
The most immediately apparent disadvantage to using XSLT is
its complexity. It's significantly harder for both programmers and
non-programmers to learn XSLT than a gentle-slope, HTML-with-substitutions
systems like Velocity. The rules-based evaluation may be unfamiliar to many
programmers at first, and the syntax is much more complicated.
Although the
Velocity syntax is more compact than the XSLT syntax, they say the same thing
essentially the same way. The sections of generated HTML with dynamically
interpolated data are nearly identical in structure, though the XSLT contains
some additional surrounding code, indicated in gray text.
Velocity
XSLT
<HTML>
<HEAD>
<TITLE>Welcome</TITLE>
</HEAD>
<BODY>
Welcome $name!
<br />
List items:
<ul>
#foreach ( $item in $items )
<li>Type: $item.type,
Quantity: $item.quantity
#end
</BODY>
</HTML>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/doc">
<HTML>
<HEAD>
<TITLE>Welcome</TITLE>
</HEAD>
<BODY>
Welcome <xsl:value-of select="name"/>!
<br />
List items:
<ul>
<xsl:for-each select="items">
<li>Type: <xsl:value-of select="@type"/>,
Quantity: <xsl:value-of select="@quantity"/>,
</xsl:for-each>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
<xsl:apply-templates>; this makes it easier
to change the styling for a list item of this particular type independently of
the rest of the page. You can do something similar with the
#include directive in Velocity but you have to explicitly name
the template to include, which couples the presentation of a list item
component more to the presentation of the page as a whole.
Performance
Page scripting
How ArsDigita uses XSLT
We use XSLT in all versions of ACS starting
with version 4.5. We chose to use it because of its strengths in building a
component-based system and for global styling. XSLT makes it easy for us to
make the presentation for page components swappable on a global basis, and to
maintain consistent styling of components on all pages where they appear.
XSLT code example: global styling and embeddable components
Suppose we
have a simple News application that displays a list of press releases. We
would represent a list of press releases as an XML document:
... and we would convert an XML list of press releases into
HTML using the following XSLT stylesheet:
<news:press-release-list>
<news:press-release href="one-article?id=2837" title="ArsDigita uses XSLT"/>
<news:press-release href="one-article?id=2838" title="Apache releases open-source XSLT engine"/>
<news:press-release href="one-article?id=2839" title="Sun adopts new Java APIs for XML"/>
</news:press-release-list>
Within ACS, we would associate this stylesheet with the
News application, as its default stylesheet. Now, any page in the News
application will display a list of press releases with the same, consistent
look-and-feel.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="news:press-release-list">
Press releases
<ul>
<xsl:for-each select="news:press-release">
<li>
<a>
<xsl:attribute name="href">
<xsl:value-of select="@href"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</a>
</li>
</xsl:for-each>
</xsl:template>
<-- more XSL template rules -->
</xsl:stylesheet>
<news:press-release-list> element, the list of press
releases will be included in the HTML output looking the same as if it were
generated from a page in the News application itself. /news/index and /cobrand/news/index, each of
which displays the same list of press releases; but the URL under /cobrand
should display the list with a different stylesheet specific to the co-brand:
This stylesheet displays press releases as table rows
instead of list items and displays a specific graphic with each row.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="news:press-release-list">
MySite.com Press Releases
<table>
<xsl:for-each select="news:press-release">
<tr>
<td><img src="my-site-icon.gif" /></td>
<td><a>
<xsl:attribute name="href">
<xsl:value-of select="@href"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</a></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<-- more XSL template rules -->
</xsl:stylesheet>
/cobrand/news/index URL, we register the stylesheet with the
/cobrand site node in the site map. When we request
/cobrand/news/index, the XSLT stylesheet used for the final
request processing is composed of the stylesheets associated with:
... in that order of
precedence.
template
match="/" rule to change the way the top-level page layout looks.
Conclusions
XSLT is promising for web presentation because it lends
itself well to web applications built from components that must have a
consistent appearance on a wide variety of pages where they may appear. There
are many advantages to using XSLT for web applications, such as co-branded,
localized portals.
Links to more resources
asj-editors@arsdigita.com
Reader's Comments
We used XSLT for an application and even if it was flexible, we needed real programmers to twist and turn the templates, especially when reviewing the site with customers and trying to obtain real time changes to get the site with the correct look and feel -- don't ask this to a designer...
-- Philippe Back, August 14, 2001
If you desire faster XML / XSLT performance then grab Resin http://www.caucho.com which includes an XML parser and XSLT transformer that are the fastest I know of. All of resin does much more than this (it's a servlet engine) but you can find docs that explain how to use its XML assets stand-alone. The source code for Resin is available and the product only costs money ($500) in certain situations.
-- David Smiley, February 4, 2002