Integration by Parts: XSLT, XLink and SVG
Introduction
If, like me, you have to repair a car, airplane (or, more modestly, the washing machine!), you'll need a parts catalog to help identify and replace some of the faulty parts.
This week's example demonstrates building an interactive illustrated parts catalog with XML technologies. The example shows how we separate the data model from the presentation, how the model is transformed into a presentation language (HTML, SVG), and finally, how scripting and CSS properties are used to implement XLink behavior and user interactivity.
Three simple steps and three XML technologies. So, let's begin with the first step.
Step 1: Encoding the Parts Catalog into XML
We won't encode an entire parts catalog in this article, just a fragment of one a single page. This page is about a small dinky toy airplane motor. The motor is the assembly of several other parts. The illustration enforces the whole-part nature of this assembly by displaying an exploded view of all the sub-parts. Each component (i.e., part) is accompanied with a visual pointer that links the component to its related information (such as its description, quantity, etc.).
In encoding the parts catalog sample, we'll use several XML technologies (such as the XLink linkage language, the SVG and HTML presentation languages, and our own custom language) to model the parts and assembly.
A part composed of other parts (such as our motor assembly)
can be perceived as a kind
of parts container. Instead of inventing a new element for
each kind of object, we simply use instead a generic
<part>
element. And, because a part can
contain other parts, a part element can contain other
<part> elements.
We just created a recursive structure.
A part also has related information. So, let's have the
<part> element contain
other elements such as the <link>,
<description> and <qty>
elements that provide, respectively, a link to a more detailed view,
a description about the part, and the quantity contained in the
assembly. Now the question is: how can we
distinguish parts that contain other parts (such as the assembly)
from the contained parts?
To model this containment relationship, we'll use the
XLink domain language. XLink is a fast-maturing W3C standard for
describing links between (and inside) documents in XML.
In particular, for our containment relationship, we will use the
xlink:extended construct, which itself is a container
of locators.
A part containing other parts is a collection. Thus, in our
model, a part containing other parts will inherit from the
xlink:extended
features and become a collection element containing locators.
A part contained in another
part inherits from the xlink:locator features and
then becomes an element contained in a collection.
Each element contained in the collection points
to a portion of the illustration (the SVG document).
If you found that a bit hard-going, the best thing to do is to look
at the resulting XML. The parts catalog document is an XML document having as its root a
<part> element. This element
inherits the xlink:extended characteristics by
including the xlink:type attribute set to
"extended." The root element also contains another
attribute, the xml:base, which defines the base
document location for all the contained locators.
The xml:base attribute value points to
the SVG document that
encodes the small motor illustration.
<part xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="extended"
xml:base="figure.svg"
xlink:title="motor">
... Locators ...
</part>
Each part contained in the motor assembly is modeled as an
xlink:locator element that refers to a numbered
circle pointing to a part in the exploded view illustration (see
Figure 1).
A contained part element (a locator) contains
a part description, a link to a more detailed view and quantity. The
<link> element points to a more detailed
external parts document if a part is composed of other parts
(i.e., if
it is an assembly itself).
That external view is another XML document encoded the same way
as the one we are describing now.
<part xlink:type="locator" xlink:href="#part-1">
<link xlink:type="simple" xlink:href="p-102-1.svg"/>
<qty>1</qty>
<description>Cylinder head</description>
</part>
Listing 1: Complete parts catalog document source
Step 2: Encoding the Illustration into SVG
The illustration is encoded into the SVG format. A major advantage of SVG is that we can manipulate it or refer to it as an XML document. Another benefit is that we can add interactivity to its content by linking its components to script functions. Thus, SVG documents are not static images, but more interactive illustrations. These interactive possibilities will be used in our parts catalog.
To create the illustration, my girlfriend Edith first
exported an AutoCAD drawing to a DXF file. This file was then
imported in Adobe illustrator and from this she produced an SVG
document. With a small Perl program, I added additional attributes
to each visual numbered pointer, but I could just as well have
used XSLT to do so.
To make life easier, we grouped each numbered circle
with a grouping element the <g> element. Then the
Perl script added to this element some attributes like
id,
style, onmouseover,
onmouseout
and onclick as shown below.
<g id="part-22"
style="cursor:hand;fill:white"
onmouseover="on_mouse_over('22')"
onmouseout="on_mouse_out('22')"
onclick="on_mouse_click('22')">
<path style="&st41;"
d="M88.231,478.266c0-4.937-4.009-8.944-8.949-8.944c-4.94,
0-8.95,4.008-8.95,8.944c0,4.938,4.01,8.944,8.95,
8.944c4.939,0,8.949-4.007,8.949-8.944"/>
<text x="72.679" y="482.308"
style="&st29; &st33; fill:black;">22</text>
</g>
The above SVG construct groups two visual objects. A circle encoded as a <path> element and a number contained in the circle. The number is encoded as a <text> element. The visual result is illustrated below
Figure 1: Visual Pointer to Part
So, with the exception of the additional attributes, most of the content has been produced by a WYSIWYG type of program. It has to be, my girlfriend is an illustrator not a programmer. Even grouping the circle (encoded as a path element) and the number (encoded as a text element) was done with the authoring tools. In fact, in recent months, the number of authoring tools able to export SVG (and in some cases even process SVG as a native format) is increasing. Here is a shortlist:
- Adobe Illustrator 8.01 With the SVG plug-in
- Corel 9 with the Corel SVG plug-in
- Jasc Trajectory Pro
- Mayura draw
As you can see from the SVG source,
the authoring tool made intensive use of the
<path> element. This is a trend that I also
noticed with several other authoring tools.
So, the illustration is encoded in a separate SVG document, and the parts catalog sample model is encoded in another XML document. To be rendered in a browser, the parts catalog document needs now to be transformed into a presentation language HTML (or XHTML).
Listing 2: The Complete SVG Illustration Document
Step 3: Transforming the XML Model into a Displayable Document
Our presentation strategy involves two languages: CSS, for the run-time dynamic modification of visual objects' properties; and XSLT, to transform the XML document into HTML.
The XSLT sheet creates an HTML document that embeds the SVG document at the top. It then adds an HTML table underneath the illustration. The table contains, for each part, related information such as the part number, description, and quantity. When the mouse cursor is over one of the illustration's visual pointers, this circled number is colored in yellow, and its related information located in the HTML table is also colored in yellow. When the user clicks on a visual pointer, it is then colored in gray and so is its related information in the table. Both visual entities stay grayed until the user clicks again on either the table row or on the illustration visual pointer. This last feature allows the user to select a particular part, then scroll the document to read the part's highlighted information.
The style sheet template associated with the XML document
(i.e., match="/") produces the core HTML constructs
and the script section. The script section contains functions that
will react at run time to events such as when the mouse
cursor is over a visual pointer, when the mouse cursor is leaving
the visual pointer, and when a mouse button is pressed.
When the mouse cursor is over a visual pointer, the style
properties (specifically, the fill attribute's value) of the
<g> element change from white to yellow.
Thus, the script dynamically changes an
SVG element's property.
This dynamic behavior is a benefit of SVG
using CSS properties for its visual objects.
The script also changes
the corresponding HTML row element's style.
Thus, both the SVG and HTML elements' visual appearance are
dynamically changed through CSS properties.
<part> elements are differentiated by the
xlink:type attribute. If the xlink:type
is set to "extended," then the template embeds the SVG document
into the rendered document. The embedded document's location is
specified by the xml:base attribute.
The template also creates an HTML table that
will include all the other contained parts, which are also
xlink:locator elements that point to other elements
contained in the SVG document.
To render the SVG document, the
freely available Adobe SVG viewer is used as a browser plug-in. This is the plug-in that is embedded in the rendered HTML document. Finally, each <part> element with an
xlink:type attribute set to "locator" is transformed
into a table row. Thus, the final rendered HTML document includes an
embedded SVG document and a table.
The Resulting HTML Document (requires SVG plug-in to view)
Analysis
Unfortunately, current reality is that browsers do not support X-Linking to elements contained in different documents. And in fact, with the exception of Mozilla (Milestone 14) and Hybrick, none support XLink constructs at all. To compensate for this weakness, scripting could be used to link elements together, to provide XLink interpretation and, more particularly, the kind of XLink behavior that you require. As you can see by viewing the result of the XSLT transformation, the elements contained in the HTML table are linked to the elements in the SVG document and vice versa.
The parts catalog document can be rendered in a browser IE5 with MSXML3.DLL installed. This will properly render the XML document by transforming it to HTML. Notice here that we used XSLT constructs that are compliant to the W3C Recommendation. You can also process the XSLT style sheet without any modifications either with XT or SAXON. (I didn't test it with Xalan or the Oracle XSLT engine but I expect that the style sheet will work with these engines too.)
For more sophisticated presentation, it seems that the combination of CSS, scripting, and XSLT is required. By modifying the CSS properties dynamically at run time, we can provide a particular XLink interpretation and behavior. If a future XSLT Recommendation includes a standard way to output multiple documents from a single style sheet, then the XLink interpretation could be provided by the XSLT style sheet.
I encourage you to play with the part catalog sample by downloading the zipped package that includes the documents I used for this experiment. A big thank you to Edith Duval who helped me create the SVG document.