From XML to SMIL
Q: How do I create a SMIL text region using XML input?
I am new to XSLT and SMIL, but I am attempting to create a SMIL presentation based on an XML document, using XSLT. Can anyone tell me how to take the text contained in my XML document, and output it to a region of my SMIL presentation? As yet I have only been able to work out how to output text using a separate .txt file, like this:
<text src="../media/audio/intro.txt"
id="intro" region="txt"/>
This works fine, but now I need to take some text from my XML file.
A: If I understand the question correctly, the answer is pretty simple. But before getting to it, some SMIL background for those who might be really new to it.
SMIL (Synchronized Multimedia Integration Language) is now at version 2.0, a full-fledged Recommendation of the W3C. (SMIL's version 1.0 was one of the first officially endorsed XML vocabularies out of the gate following the release of the XML 1.0 Recommendation in 1998.) But what is it?
SMIL defines an XML vocabulary for describing the content and presentation of not just text, but also images, audio, and all the other beasts in the multimedia zoo. A SMIL document defines the layout of the presentation -- where visual objects are placed physically in a window -- as well as its timing -- how long to display a particular window or portion of it.
Here's an example, taken from the SMIL Recommendation:
<smil
xmlns="http://www.w3.org/2001/SMIL20/">
<head>
<layout>
<root-layout width="320" height="480" />
<region id="a" top="5" />
</layout>
</head>
<body>
<text region="a" src="text.html" dur="10s" />
</body>
</smil>
Translated, this establishes a simple presentation, the characteristics of which include the following:
Of particular interest to the questioner is the
text element. Like all the so-called SMIL media object
elements (the others include, for example, video,
audio, and img),
text is always an empty element: its "content" is
located not in the SMIL document itself, but merely pointed to by
way of the src attribute. This is where the
questioner is getting hung up.
A SMIL document author who wants to include the text content of an XML document has two choices:
src attribute in the expected manner (as in the
example above from the SMIL Rec).src attribute value to
include literal text.Each approach has its pros and cons. I'll discuss them in turn, and use the following as the XML document whose content is to be included in the SMIL presentation:
<mydoc>
<verbiage>Now is the winter of our
discontent</verbiage>
</mydoc>
This option requires a separate step, run once (whenever the XML
document's content changes). That step is an XSLT transformation to
extract the XML document's content and save it to a simple text file;
this text file then becomes the target of the text
element's src attribute.
The key to a transformation such as this is to use in the
stylesheet an xsl:output element, with a
method attribute whose value is "text". For this
extremely simple sample document, a stylesheet such as the
following will suffice:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="verbiage">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Directing the output of the transformation to a file enables you to
use a SMIL text element just as the questioner
proposes:
<text src="intro.txt" id="intro"
region="txt"/>
The advantage of this option is that it's relatively simple. The disadvantage is that, despite the simplicity, it's also somewhat inelegant. This is especially true if you've got a lot of text elements in your SMIL presentation, each with different content, even if the content for them all is derived from the same XML source document. In this case, you need to run a separate transformation -- resulting in a separate text file -- for each text element. You may end up having to juggle way too many files for your comfort: an intro.txt, yes, but also (say) a slide01.txt through slidenn.txt.
You won't, to my knowledge, find this option described anywhere in the SMIL 2.0 Recommendation. That's because it relies on an otherwise seldom-used form of a URI; this form, the "data" scheme, is documented in the Internet Engineering Task Force (IETF) RFC2397 -- dating (like SMIL itself, come to think of it) all the way back to the summer of 1998.
The data scheme, unlike other URI forms, doesn't open with a
protocol signifier (expressed in an absolute URI or implied in a
relative one) such as http://, ftp://,
or gopher://. Furthermore, it doesn't point to external
content. Rather, it embeds the content directly in the URI itself, as
inline data. Here's an example of such a URI as it might appear in the
questioner's SMIL presentation:
<text
src="data:text/plain,Introduction"
id="intro" region="txt" />
A data-schemed URI thus consists of the word data
followed by a colon, an Internet media type (here,
text/plain), a comma, and the inline content itself. If
the Internet media type is text/plain, it may be omitted,
in which case the colon is followed directly by the comma:
<text
src="data:,Introduction"
id="intro"
region="txt"
/>
Simple enough so far. The catch, of course, is that the questioner's content still resides entirely in an external file. Ultimately what this suggests is that you shouldn't handcraft your SMIL presentation at all; instead, use XSLT to crank it out, with your external document as the source tree. A portion of such a stylesheet, given our sample XML document, might look like this:
<xsl:template match="verbiage">
<text src="data:,{.}"
id="intro" region="txt"
/>
</xsl:template>
Note that the src attribute's value contains an
attribute value template (AVT) delimited by curly braces. This AVT
instructs the XSLT processor to replace the curly-braced expression
with the string-value of the context node -- i.e., in this case,
the verbiage element. Also note that because the result
of the transformation is to be SMIL, which is a form of XML, the
stylesheet should not include the <xsl:output
method="text"/> code used in the previous example.
When passed through an XSLT processor such as Saxon, this transformation produces the expected result:
<text src="data:,Now is the winter of our
discontent" id="intro"
region="txt"
/>
Expected, yes. Unfortunately, we're not out of the woods yet: the "data" URI scheme, odd-looking though it is, must still conform to the rules of other URI schemes. Among those rules are that certain special characters must be escaped, including spaces.
You probably already know that the proper URI escape sequence for a
space is %20. Thus, what we need to end up with is a text
element which looks like this:
<text
src="data:,Now%20is%20the%20winter%20of%20our%20discontent"
id="intro" region="txt"
/>
Depending on the SMIL processor you intend to use, and the server (if any) involved, you may also be able to substitute a plus sign for each space:
<text
src="data:,Now+is+the+winter+of+our+discontent"
id="intro" region="txt"
/>
Regardless of the replacement characters, this might seem an
insurmountable difficulty -- requiring, as an XSLT-phobic imagination
might have it, some kind of exotic substring-and-test operation
against each character in the inline text. If you're lucky and can use
the plus signs, calm down, recalling the availability of
XSLT's transform() function. (I leave to you, fortunate
ones, the working out of the actual XSLT code at this point.) If
you're not so lucky, you may indeed need additional help; in this
case, look into using one of the implementations of the
EXSLT str:encode-uri() function or the XQuery
escape-uri() function.
(By the way, spaces aren't the only special characters in URIs which require escaping. Others may be found in Section 2.4 of IETF RFC2396, "Uniform Resource Identifiers (URI): Generic Syntax.")
Ultimately, you'll have to answer that question for yourself. It depends on your requirements, your skill, and comfort levels with XSLT and SMIL, and perhaps your personal taste. I would probably choose Option 2. I like the idea of machine-generating SMIL documents rather than hand-coding them and working backwards to shoehorn the content into the hand-coded framework. For the same reason, I'd resist hand-coding SVG and XSL-FO documents, but those are subjects for later columns, not this one.
XML.com Copyright © 1998-2006 O'Reilly Media, Inc.