A lot of the early hype around XML (some of which I was personally guilty of, I admit) promised that you'd be able to write markup that fit your use case and serve it to clients along with a stylesheet that explained how they should render the content. As often happens, however, things didn't work out exactly as planned. Poor browser support meant the rendering happened on the server more often than on the client. Fortunately, XSLT and CSS together did a fairly good job of allowing developers to use text-based applications like DocBook and BiblioML as authoring formats without requiring browsers to have detailed knowledge of each application.
However, both XSL and CSS were designed to work primarily with text data; they don't really suit formats that don't describe text, such as MusicXML or MathML. Both CSS and XSL Formatting Objects (XSL-FO) assume that they're styling words in a row: chapters, paragraphs, sentences, and so on. When fully implemented, they're completely adequate for these uses, including more advanced layouts with tables, embedded graphics, and running columns. Unfortunately, neither CSS nor XSL-FO is capable of rendering a complicated mathematical equation or a bar of music. And while XSLT could generate PostScript pictures or some other such format (it is Turing complete, after all), that's hardly what's it was designed to do; nor is such a program practical, even if it's theoretically possible. XSL, CSS, and other existing stylesheet languages are designed to render text, not graphics. However, users are now marking up non-text content in XML -- including maps, engineering diagrams, music, mathematics, comic strips, and graphs -- so they need a stylesheet language that can handle these vocabularies, too.
SVG's XML Binding Language (sXBL) is a new technology being spun out of SVG 1.2 and
Mozilla's XBL. This binding language allows you to define a mapping between any vocabulary and SVG. For example, you
can say that MathML's
<root/> element should be mapped to four SVG line elements that
together draw the radical sign √. You can say that MusicXML's
<clef/> element with a
<sign>g</sign> child should be mapped to a Bezier curve that draws a G-clef .
Because SVG is powerful enough to draw essentially any two-dimensional graphic, you can use sXBL to render anything
that can be drawn in two dimensions. (Autocad models, X3D, and other three-dimensional objects still need a custom renderer.)
sXBL works much like XSLT. More specifically, it works like a special kind of XSLT stylesheet called literal result element used as stylesheet -- that is, an sXBL stylesheet (the spec doesn't actually use the word stylesheet, but that's how I think of it) is an SVG document. This document can contain content from other namespaces. It also specifies bindings between elements in those namespaces and particular SVG shapes. When an SVG processor renders the complete document, it replaces the content from other namespaces with their SVG bindings. Any elements from other namespaces that are not bound to SVG elements are simply dropped out.
As an example, consider the periodic table expressed in XML. I first wrote this document as an example in the XML Bible,
and it has since been used as a component of several XML benchmarks and test suites. The document consists of more than 100
ATOM elements like this one:
<ATOM> <NAME>Aluminum</NAME> <ATOMIC_WEIGHT>26.98154</ATOMIC_WEIGHT> <ATOMIC_NUMBER>13</ATOMIC_NUMBER> <SYMBOL>Al</SYMBOL> <ELECTRON_CONFIGURATION>[Ne] 3s2 p1</ELECTRON_CONFIGURATION> </ATOM>
Suppose you want to format this code as a typical cell of a periodic table, as Figure 1 shows.
Figure 1. The rendered aluminum element
Generally, the first step to designing a stylesheet in either XSLT or sXBL is to write a variation of the document you want to create. So take a look at a pure SVG implementation of this picture, shown in Listing 1.
Listing 1. An SVG rendering of an element
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <svg xmlns="http://www.w3.org/2000/svg" width="101" height="101"> <rect x="0" y="0" width="100" height="100" stroke="black" stroke-width="2px" fill="none"/> <text x="40" y="30" font-size="12pt" font-family="Helvetica, Arial, sans">13</text> <text x="40" y="50" font-weight="bold" font-size="14pt" font-family="Helvetica, Arial, sans">Al</text> <text x="13" y="65" font-size="12pt" font-family="Helvetica, Arial, sans">Aluminum</text> <text x="14" y="85" font-size="12pt" font-family="Helvetica, Arial, sans">26.98154</text> </svg>
Now, you need to rewrite this SVG so that instead of hard coding the name, symbol, atomic number, and atomicd, those items are read from the
ATOM element. To do so, write an sXBL definition for the
ATOM element. This is a
definition element in the
http://www.w3.org/2004/xbl namespace. (Henceforth, I assume that this namespace
is bound to the
xbl prefix without further comment.) The definition contains an
xbl:template element, which itself contains the SVG code that will replace each
ATOM element in the input document. For example:
<xbl:xbl id="atoms" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:xbl="http://www.w3.org/2004/xbl"> <xbl:definition element="ATOM"> <xbl:template> <rect x="0" y="0" width="100" height="100" stroke="black" stroke-width="2px" fill="none"/> </xbl:template> </xbl:definition> </xbl:xbl>
(Note: The sXBL namespace URI is likely to change before the final release of the sXBL specification.)
This definition maps each
ATOM element to an SVG
with a width and height of 100 at positions x=0 and y=0, and a 2-pixel stroke width and no fill. You can put this element
svg:defs element in an SVG document, along with the actual data, as Listing 2 shows.
Listing 2. Binding custom markup to SVG
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <svg xmlns="http://www.w3.org/2000/svg"version="1.2" xmlns:chem="http://ns.cafeconleche.org/chemistry/" xmlns:xbl="http://www.w3.org/2004/xbl" width="101" height="101"> <defs> <xbl:xbl id="atoms" > <xbl:definition element="chem:ATOM"> <xbl:template> <rect x="0" y="0" width="100" height="100" stroke="black" stroke-width="2px" fill="none"/> </xbl:template> </xbl:definition> </xbl:xbl> </defs> <chem:ATOM> <chem:NAME>Aluminum</chem:NAME> <chem:ATOMIC_WEIGHT>26.98154</chem:ATOMIC_WEIGHT> <chem:ATOMIC_NUMBER>13</chem:ATOMIC_NUMBER> <chem:SYMBOL>Al</chem:SYMBOL> <chem:ELECTRON_CONFIGURATION>[Ne] 3s2 p1</chem:ELECTRON_CONFIGURATION> </chem:ATOM> </svg>
When processed, each
ATOM element found in this document will be replaced by
the content of the matching sXBL template. So far, that's just a static rectangle. However, you also want to include
the name, symbol, atomic number, and atomic weight; you can select each of these by using an
xbl:content element in the template. Exactly how the content element will choose the
content to include is still under discussion by the W3C working group. However, all the proposals are based on
XPath, and allow at least child element names. Listing 3 shows how the template can place child element content
from the chemistry namespace into the rendered SVG.
Listing 3. Adding content from the source vocabulary to the SVG
<xbl:definition element="ATOM"> <xbl:template> <rect x="0" y="0" width="100" height="100" stroke="black" stroke-width="2px" fill="none"/> <text x="40" y="30" font-size="12pt" font-family="Helvetica, Arial, sans"> <content includes="ATOMIC_NUMBER"/> </text> <text x="40" y="50" font-weight="bold" font-size="14pt" font-family="Helvetica, Arial, sans"> <content includes="SYMBOL"/> </text> <text x="13" y="65" font-size="12pt" font-family="Helvetica, Arial, sans"> <content includes="NAME"/> </text> <text x="14" y="85" font-size="12pt" font-family="Helvetica, Arial, sans"> <content includes="ATOMIC_WEIGHT"/> </text> </xbl:template> </xbl:definition>
The value of the
includes attribute is an XPath expression (possibly chosen from a
very restricted subset of XPath) that identifies the element whose text is included. The context node for this XPath
expression is the element that the template is replacing -- in this case, an
So far, I've kept everything in one document. However, you can modularize the content by breaking the file up into
three or more parts. Typically, one document will include the sXBL definitions and templates, one will include the
non-SVG XML data being rendered, and one will include the SVG container document. For example, Listing 4 shows
such a container document. An XInclude
include element references the original XML
document at http://cafeconleche.org/examples/periodic_table/allelements.xml. An
element loads the templates found at the relative URL atom_bindings.sxbl. However, this document requires a
separate XInclude processing step. XInclude support is not necessarily built into all (or any) sXBL renderers.
Listing 4. Store content, bindings, and templates in separate documents
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <svg xmlns="http://www.w3.org/2000/svg"version="1.2" xmlns:chem="http://ns.cafeconleche.org/chemistry/" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xbl="http://www.w3.org/2004/xbl" width="101" height="101"> <defs> <xbl:xbl id="atoms" > <xbl:import bindings="atom_bindings.sxbl"/> </xbl:xbl> </defs> <xi:include href= "http://cafeconleche.org/examples/periodic_table/allelements.xml" /> </svg>
You can, if you wish, add additional SVG markup to this document that will appear on the rendered page, though not on each separate rendered atom.
Longer term, the W3C working group is planning to implement target formats other than SVG. For example, you'll be able to use similar techniques to write stylesheets that produce XUL or XAML to bind directly into the browser. It seems likely that sXBL will become a key part of the next-generation World Wide Web.
- Explore the other new features in SVG 1.2.
- Read the latest sXBL specification from the W3C.
- Before you can script sXBL, you'll need to learn how to
- Antoine Quint has also explored scripting SVG through the DOM.
- sXBL is a direct descendant of the Mozilla Project's Extensible Binding Language 1.0 (XBL) and both will eventually be replaced by XBL 2.0.
- Scan an online interactive version of the periodic table of the elements.
- Browse for books on these and other technical topics.
- Find hundreds more XML resources on the
developerWorks XML zone, including the tutorials "Introduction to Scalable Vector Graphics" (March 2004) and "Interactive, dynamic Scalable Vector Graphics" (June 2003).
- Learn how you can become an IBM Certified Developer in XML and related technologies.
Elliotte Rusty Harold is originally from New Orleans, to which he returns periodically in search of a decent bowl of gumbo. However, he resides in the Prospect Heights neighborhood of Brooklyn with his wife Beth and cats Charm (named after the quark) and Marjorie (named after his mother-in-law). He's an adjunct professor of computer science at Polytechnic University, where he teaches Java and object-oriented programming. His Cafe au Lait Web site has become one of the most popular independent Java sites on the Internet, and his spin-off site, Cafe con Leche, has become one of the most popular XML sites. His books include Effective XML, Processing XML with Java, Java Network Programming, and The XML 1.1 Bible. He's currently working on the XOM API for processing XML and the XQuisitor GUI query tool. You can contact him at email@example.com.