Menu

A Mobile Window on our Portal

May 31, 2000

Didier Martin


In the previous Style Matters column, we saw that XML-encoded documents used for Internet/extranet/intranet portals give us the benefit of presentation independence. The same XML document can be displayed on a desktop browser and on a digital cellular phone browser using two different XSLT sheets. As you know, desktop browsers render HTML documents and digital cellular phone browsers render WML documents. Thus, the same XML document may be transformed into HTML with one XSLT transformation sheet and into WML with another.

In fact, we should mention here that not all digital cellular phone browsers are able to render WML documents -- a lot of them are only able to render HDML documents. HDML is an SGML-based language, and could be considered the ancestor of WML. This week, we'll only talk about WML rendering and keep HDML for the next Style Matters column.

The equipment you'll need for this week's lab can be obtained from http://www.phone.com/developers/index.html. From there, you'll be able to get a WML browser emulator. You'll also need a local HTTP server.

A Brief Introduction to WML

A WML document uses the XML document character set -- currently the Universal Character Set of ISO/IEC-10646 (Unicode 2.0) -- and supports any proper subset of the Unicode character set (for example, US-ASCII, ISO-8859-1, or UTF-8). All WML documents should have a doctype declaration in the document's prolog. So, a WML document should start with

<?xml version="1.0"?>

<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD wml 1.1//EN" 

"http://www.wapforum.org/DTD/wml_1.1.xml">

As can be seen from the doctype declaration, the WML document's root element is the <wml> element. Be cautious with uppercase and lowercase handling; we are in XML lands and XML parsers are case sensitive. So, the <wml> element's name is to be written in lower case characters. The <wml> element contains <card> elements:

<?xml version="1.0"?>

<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD wml 1.1//EN"

"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>

 <card>

  ...

 </card>

 <card>

  ...

 </card>

</wml>

In contrast to HTML documents, which are based on a single scrollable page, WML documents are a collection of pages, known as cards. A WML document is a collection of cards--this collection is referred to as a deck. We should keep in mind that most WML browser screens are limited to four lines of 12 characters. So a card will be rendered, most of the time, in a small screen. This small screen is also scrollable in most implementations. You can think of a card as being simply an interaction activity with the user. Something like, "select an item," "read text," or "enter data." If a card is too big to fit on a device's screen, then the card's content may scroll, or it may be split into a series of screens.

The <card> element can contain several types of child elements, such as

  • <onevent>

  • <timer>

  • <do>

  • <a>

  • <fieldset>

  • <img>

  • <input>

  • <select>

  • <p>

Several of these elements, like the <a>, <input>, and <select> elements, are also part of the HTML vocabulary. Some browsers, like Internet Explorer, may even render WML documents because of the fact that both languages share the same constructs. Try this yourself by simply changing the file extension from ".wml" to ".html" and then see Internet Explorer rendering the elements common to both languages.

Some of these elements have to be in a specific order. Thus the content of a <card> element should respect a certain order for its children elements:

  1. <onevent>

  2. <timer>

  3. <do>

The <onevent> is to be the first, the <timer> element the second, and so forth. All the other elements will be rendered in the order in which you specify them.

Mapping our Portal to a WML Rendering

To give our portal page a WML rendering, we will use an XSLT style sheet (often called a "transformation sheet"--don't worry, both names refer to the same thing).

WML browsers do not like any namespace declarations to be included in the <wml> root element. Here is the trick to restrain your XSLT engine from any impulses to include namespace declarations, especially if you included some namespace declarations in your style sheet and the source XML document.

<xsl:stylesheet

 xmlns:xinclude="http://www.w3.org/1999/XML/xinclude"

 xmlns:xlink="http://www.w3.org/TR/xlink"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

 exclude-result-prefixes="xinclude xlink"

 version="1.0">

The <xsl:stylesheet> element is the root element for XSLT style sheets. To keep the WML browser happy, we added to the root element the exclude-result-prefixes attribute. This tells the XSLT engine to use some self control, and not include any namespace declarations in the result tree (i.e., the WML document).

In the last article, we presented an XML document used to model our portal page. In this XML document, each information unit is enclosed in a <netfolder> element. This element brings in a news feed from a web service. The web service accepts URL queries and return XML documents. We used the <xinclude:include> element to indicate that external content is to be included in our portal page.

The XInclude interpreter is an XSLT transformation sheet, which uses the document() function in an XPath expression to pull XML content from web services. Other parts of the XPath expression are used to extract a fragment from the included XML document. This fragment replaces the <xinclude:include> element and then is further translated (as is the rest of the document) into the target rendering language vocabulary set. For today, the target rendering language is WML. We will use a simplified version of the last article's portal document.

Each <netfolder> element is transformed into a display unit. In the case of HTML, we created a portal window for each <netfolder> element. In the case of WML, each <netfolder> element is to be transformed into a card. This is not completely straightforward, as WML cards need to be referred to with IDs, and referring to external element IDs using only XSLT is not an easy task. To simplify things, we would need an XInclude interpreter that merged all the documents prior to any XSLT processing. By treating the document as a whole, referring to IDs would be a lot simpler. I instead opted for a short cut so that we'd have more time for more explanations about the XSLT transformation sheet.

Not having an XInclude interpreter on hand (I have one in my labs, but unfortunately not yet ready for wider distribution), we will create one with XSLT just to illustrate a way to pull XML content from external sources. This is accomplished by the following template:

<xsl:template match="xinclude:include">

 <xsl:apply-templates select="document(@href)/topic-list"/>

</xsl:template>

This is our XInclude interpreter. It pulls content from an external document and applies the templates to the XML tree the document() function created. This function returns a node list, and the XSLT engine tries to match templates on this node list.

Now our main goal is to display the news feed headlines, as illustrated by Figure 1.

Figure 1: News feed headlines on mobile browser

The following XSLT style sheet performs the transformation from information unit to display units.

<xsl:template match="topic[@xlink:type='extended']">

 <card>

   <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>

   <xsl:attribute name="title"><xsl:value-of select="@xlink:title"/></xsl:attribute>

   <xsl:apply-templates select="xinclude:include" />

   <p>

     <em>My portal Headlines</em>

     <select name="type" title= "MobilePortal"><br>

       <xsl:for-eachselect="topic[@xlink:type='locator']">

         <option>

           <xsl:attribute name="value"><xsl:value-of

                                 select="@id"/></xsl:attribute>

           <xsl:attribute name="onpick">#<xsl:value-of

                                 select="@id"/></xsl:attribute>

           <xsl:value-of select="@xlink:title"/>

         </option>

       </xsl:for-each>

     </select>

   </p>

 </card>

 <xsl:apply-templates/>

</xsl:template>

The template matches any <topic> element that contains an attribute set with the value extended. When the template matches such element, the XSLT engine includes in the result tree a <card> element. The <card> element has two attributes: id and title. These attributes are created with the <xsl:attribute ...> element. The values of these attributes are created with the <xsl:value-of> construct. This last construct is quite useful for pulling content out of an info set (i.e., the internal model--after parsing--of an XML document). The select attribute's values are XPath expressions that extract the value of the two <topic> attributes: id and xlink:title.

We then insert a <p> element as child of the <card> element. Inside the <p> element, we include a widget that allows the user to select a headline from several options. This is provided by the <select> element. Do you have a feeling of déjà vu? Of course, the <select> element is also part of the HTML vocabulary!

The <select> element's content is created by a loop, which for each <topic> element having an attribute xlink:type equal to "locator," the XSLT engine should create an <option> element. We apply the same treatment to the <option> element that we did for the <card> element, and use the <xsl:attribute> construct to add the value and name attributes to the <option> element. The result created by the template is shown in Figure 1.

Finally, when the user selects a headline, its abstract is displayed as a paragraph, as shown in Figure 2.

Figure 2: Display of a story abstract

The template for the <abstract> element simply produces a paragraph, represented in WML as it would be in HTML, with a <p> element. Check out the full XSL source to see this template. The final WML should give you a good idea of how it all works.

Endnotes

Digital phones are not only limited by their display capabilities, but also by their memory limitations. So, check the document size produced by your transformation sheets. Most WML browsers impose a limit on the document size. You may have to use XSLT extensions to create several documents from your portal XML document. Cards can be reorganized to fit in documents with a file size below the maximum allowed.

WML is quite similar to HTML, and this reduces the learning curve for those of us accustomed to the HTML vocabulary. The main difficulty is not in learning the WML rendering language, but more in dealing with the screen real estate and memory limitations.

Very useful for processing WML would be an XInclude interpreter to aggregate the XML external contents prior to XLST processing. This would simplify referring to elements by ID a lot. Another tool in my WML toolkit is an XSLT engine able to output more than one document (most XSLT processors have this available as an extension function). This is particularly useful when you have to chunk the content in compiled WML pages that are to be less than 1.4K. (How do you know if the produced page will be below the maximum size limit? Just use a zip compressor on the WML text document, and check the file size. This should give you a good guesstimate if your file is within the browser file size tolerance.)

In the next column, we'll demonstrate how to create an HDML document with a DSSSL transformation sheet. Until then, have fun in your XML lab.