Your First XSLT Style Sheet

With just enough XSLT knowledge to get you in trouble, why not go ahead and tackle a complete example style sheet? Don't worry, this example shouldn't be too hard to grasp because it is focuses on familiar territory. I'm referring to the Contacts example XML document from Styling XML Content With CSS. If you recall, in that tutorial you created a CSS style sheet to display the content from an XML document containing a list of contacts. Now it's time to take a look at how similar functionality is carried out using an XSLT style sheet. In fact, you take things a bit further in the XSLT version of the Contacts style sheet. To refresh your memory, the Contacts XML document is shown in Listing 11.1.

Listing 11.1. The Familiar Contacts Example XML Document
 1: <?xml version="1.0"?>
 2: <?xml-stylesheet type="text/xsl" href="contacts.xsl"?>
 3: <!DOCTYPE contacts SYSTEM "contacts.dtd">
 5: <contacts>
 6:   <! This is my good friend Frank. >
 7:   <contact>
 8:     <name>Frank Rizzo</name>
 9:     <address>1212 W 304th Street</address>
10:     <city>New York</city>
11:     <state>New York</state>
12:     <zip>10011</zip>
13:     <phone>
14:       <voice>212-555-1212</voice>
15:       <fax>212-555-1342</fax>
16:       <mobile>212-555-1115</mobile>
17:     </phone>
18:     <email>[email protected]</email>
19:     <company>Frank&apos;s Ratchet Service</company>
20:     <notes>I owe Frank 50 dollars.</notes>
21:   </contact>
23:   <! This is my old college roommate Sol. >
24:   <contact>
25:     <name>Sol Rosenberg</name>
26:     <address>1162 E 412th Street</address>
27:     <city>New York</city>
28:     <state>New York</state>
29:     <zip>10011</zip>
30:     <phone>
31:       <voice>212-555-1818</voice>
32:       <fax>212-555-1828</fax>
33:       <mobile>212-555-1521</mobile>
34:     </phone>
35:     <email>[email protected]</email>
36:     <company>Rosenberg&apos;s Shoes &amp; Glasses</company>
37:     <notes>Sol collects Civil War artifacts.</notes>
38:   </contact>
39: </contacts>

The only noticeable change in this version of the Contacts document is the xml-stylesheet declaration (line 2), which now references the style sheet file contacts.xsl. Beyond this change, the document is exactly as it appeared in Styling XML Content With CSS. In Styling XML Content With CSS, the role of the XSLT style sheet was to display the contacts in a format somewhat like a mailing list, where the phone numbers, email address, company name, and notes are hidden. This time around the style sheet is going to provide more of a contact manager view of the contacts and only hide the fax number, company name, and notes. In other words, you're going to see a more complete view of each contact.

Before getting into the XSLT code, it's worth reminding you that XSLT isn't directly capable of formatting the document content for display; don't forget that XSLT is used only to transform XML code. Knowing this, it becomes apparent that CSS must still enter the picture with this example. However, in this case CSS is used purely for display formatting, whereas XSLT takes care of determining which portions of the document are displayed.

In order to use CSS with XSLT, it is necessary to transform an XML document into HTML, or more specifically, XHTML. If you recall, XHTML is the more structured version of HTML that conforms to the rules of XML. The idea is to transform relevant XML content into an XHTML web page that uses CSS styles for specific display formatting. The resulting XHTML document can then be displayed in a web browser. Listing 11.2 contains the XSLT style sheet (contacts.xsl) that carries out this functionality.

Listing 11.2. The contacts.xsl Style Sheet Used to Transform and Format the Contacts XML Document
 1: <?xml version="1.0"?>
 2: <xsl:stylesheet version="1.0"
 3:   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 4:   xmlns="http://www.w3.org/1999/xhtml">
 5:   <xsl:template match="/">
 6:     <html xmlns="http://www.w3.org/1999/xhtml">
 7:       <head><title>Contact List</title></head>
 8:       <body style="background-color:silver">
 9:         <xsl:for-each select="contacts/contact">
10:           <div style="width:450px; padding:5px; margin-bottom:10px;
11:           border:5px double black; color:black; background-color:white;
12:           text-align:left">
13:             <xsl:apply-templates select="name"/>
14:             <xsl:apply-templates select="address"/>
15:             <xsl:apply-templates select="city"/>
16:             <xsl:apply-templates select="state"/>
17:             <xsl:apply-templates select="zip"/>
18:             <hr />
19:             <xsl:apply-templates select="phone/voice"/>
20:             <xsl:apply-templates select="phone/mobile"/>
21:             <hr />
22:             <xsl:apply-templates select="email"/>
23:           </div>
24:         </xsl:for-each>
25:       </body>
26:     </html>
27:   </xsl:template>
29:   <xsl:template match="name">
30:     <div style="font-family:Verdana, Arial; font-size:18pt; font-
31:       <xsl:value-of select="."/>
32:     </div>
33:   </xsl:template>
35:   <xsl:template match="address">
36:     <div style="font-family:Verdana, Arial; font-size:14pt">
37:       <xsl:value-of select="."/>
38:     </div>
39:   </xsl:template>
41:   <xsl:template match="city">
42:     <span style="font-family:Verdana, Arial; font-size:14pt">
43:       <xsl:value-of select="."/>,&#32;
44:     </span>
45:   </xsl:template>
47:   <xsl:template match="state">
48:     <span style="font-family:Verdana, Arial; font-size:14pt">
49:       <xsl:value-of select="."/>&#32;
50:     </span>
51:   </xsl:template>
53:   <xsl:template match="zip">
54:     <span style="font-family:Verdana, Arial; font-size:14pt">
55:       <xsl:value-of select="."/>
56:     </span>
57:   </xsl:template>
59:   <xsl:template match="phone/voice">
60:     <div style="font-family:Verdana, Arial; font-size:14pt">
61:       <img src="phone.gif" alt="Voice Phone" />&#32;
62:       <xsl:value-of select="."/>
63:     </div>
64:   </xsl:template>
66:   <xsl:template match="phone/mobile">
67:     <div style="font-family:Verdana, Arial; font-size:14pt">
68:       <img src="mobilephone.gif" alt="Mobile Phone" />&#32;
69:       <xsl:value-of select="."/>
70:     </div>
71:   </xsl:template>
73:   <xsl:template match="email">
74:     <div style="font-family:Verdana, Arial; font-size:12pt">
75:       <img src="email.gif" alt="Email" />&#32;
76:       <xsl:value-of select="."/>
77:     </div>
78:   </xsl:template>
79: </xsl:stylesheet>

I know, there is quite a bit of code in this style sheet. Even so, the functionality of the code is relatively straightforward. The style sheet begins by declaring the XSLT and XHSTML namespaces (lines 34). With that bit of standard bookkeeping out of the way, the style sheet creates a template used to match the root element of the document (line 5); this is indicated by the match attribute being set to /. Notice that within this template there is XHTML code that is used to construct an XHTML web page. Inside the body of the newly constructed web page is where the interesting things take place with the style sheet (lines 924).

An xsl:for-each element is used to loop through the contact elements in the document (line 9); each of the contacts is displayed inside of a div element. The specific content associated with a contact is inserted into the div element using the xsl:apply-templates element to apply a template to each piece of information. More specifically, templates are applied to the name, address, city, state, zip, phone/voice, phone/mobile, and email child elements of the contact element (lines 1322), along with a couple of horizontal rules in between the templates to provide some visual organization. Of course, in order to apply these templates, the templates themselves must exist.

The first child template matches the name element (lines 2933) and uses CSS to format the content in the name element for display. Notice that the xsl:value-of element is used to insert the content of the name element into the transformed XHTML code. The dot (.) specified in the select attribute indicates that the value applies to the current node, which is the name element. Similar templates are defined for the remaining child elements, which are transformed and formatted in a similar fashion.

The end result of this style sheet is a transformed XHTML document that can be viewed as a web page in a web browser. Figure 11.2 shows the resulting web page generated by this XSLT style sheet.

Figure 11.2. The Contacts example document is displayed in Internet Explorer using the contacts.xsl style sheet.

The figure reveals how the contacts.xsl style sheet carries out similar functionality as its CSS counterpart from Styling XML Content With CSS, but with noticeably more flair. The flexibility of being able to transform XML code into any XHTML code you want is what allows the XSLT version of the Contacts style sheet to look a bit flashier. Again, this is because the XSLT style sheet is literally transforming XML content into XHTML content, applying CSS styles to the XHTML, and ultimately making the end result available for display in a web browser. Although this style sheet certainly demonstrates the basic functionality of XSLT, it doesn't touch the powerful transformation features at your disposal with XSLT. I'll leave that for the next tutorial.