Transforming XML Content

Keeping XML content separate from its presentation allows you to apply many different looks to the same information. It lets you present the XML data on different devices. The requirements for displaying an XML document on a website are likely to be very different from those for printing it out or displaying it on a mobile telephone, even though the data will be the same.

Transformations are a powerful way to change the presentation of your data. Transforming means displaying, sorting, filtering, and printing the information contained within an XML document. You can use Cascading Style Sheets (CSS) to change the way your XML elements display in a web browser. XSL transformations allow you to change the display as well as include more advanced options such as sorting and filtering.

CSS

An easy way to transform the visual appearance of XML documents is by using CSS. CSS is a recommendation from the W3C. You can find out more at www.w3c.org/Style/CSS/.

CSS and XML work together in much the same way as CSS and HTML. You can use CSS to redefine the way XML tags display in a web browser. You include a reference to an external style sheet by adding a processing instruction below your XML declaration:

 <?xml version="1.0"?> <?xml-stylesheet href="styles.css" type="text/css"?> 

This is much the same as the HTML instruction:

 <link href="styles.css" rel="style sheet" type="text/css"> 

As with HTML pages, you can include multiple style sheet links:

 <?xml-stylesheet href="globalstyles.css" type="text/css"?> <?xml-stylesheet href="newsstyles.css" type="text/css"?> <?xml-stylesheet href="homestyles.css" type="text/css"?> 

The style declarations contained with the style sheets change the appearance of the XML elements. Each style declaration refers to a different element in the XML document. They are the same CSS declarations that you would use in HTML pages, so you can change font characteristics, borders, and colors for each element.

In addition to the standard style declarations, you need to consider whether the element is a block-level or inline element. In HTML, tables and headings are block-level elements while <span> is an inline element. Block-level elements automatically display with white space. In XML, all elements are inline by default. Youll need to declare block-level elements explicitly using the style declaration display: block .

This listing shows style declarations from the addressCSS.xml file:

 contact {   display: block;   margin: 5px; } name {   display: block;   font-weight: bold;   font-size: 16px;   color: #0033CC;   font-family: Verdana, Arial, sans-serif; } address {   font-weight: normal;   font-size: 12px;   font-family: Verdana, Arial, sans-serif; } phone {   display: block;   font-weight: normal;   font-size: 12px;   color: #0033CC;   font-family: Verdana, Arial, sans-serif; } 

The style sheet is saved as styles.css . Note that the file contains a style declaration for every element in the XML document.

Figure 3-30 shows the file addressCSS.xml file opened in a web browser. It looks very different from the raw XML document.

image from book
Figure 3-30: Internet Explorer showing an XML document transformed with CSS

As you can see in this example, I had to specify a style for each of my XML elements. In a large XML file, this is likely to be time consuming. CSS displays the XML elements in the same order that they appear in the XML document. I cant use CSS to change this order of the elements.

The W3C has released a recommendation titled Associating Style Sheets with XML Documents at www.w3.org/TR/xml-stylesheet/.

CSS changes the way that an XML file renders in the web browser. It doesnt offer any of the more advanced transformations that are available through XSL Transformations (XSLT). CSS may be of limited value because, unlike HTML pages, XML documents arent always designed to be displayed in a web browser.

Bear in mind also that search engines and screen readers are likely to have difficulty when working with XML pages displayed with CSS. Search engines use the <title> tag, which isnt likely to be present in the same way in most XML documents. Screen readers normally require a system of headings <h1> , <h2>, and so onto make sense of content. It will be difficult for people using a screen reader to make sense of a document that uses nonstandard tag names .

XSL

Extensible Stylesheet Language (XSL) is another way to change the display of XML documents. XSL transforms one XML document into another. As XHTML is a type of XML, you can use XSL to transform XML into an XHTML web page.

XSL is made up of XSLT and XSL-FO (XSL Formatting Objects), and relies heavily on XPath. You can use XSLT to transform one XML document into another. XSL-FO deals with the formatting of printed documents, and both use XPath to identify different parts of an XML document. We normally use XSL-FO for more complex types of printed transformations, so well focus on XSLT in this section.

At the time of writing, the XSL version 1 recommendation was available at www.w3.org/TR/2001/REC-xsl-20011015/. The version 1.1 working draft is at www.w3.org/TR/2004/WD-xsl11-20041216/.The XSLT version 1 recommendation is at www.w3.org/TR/1999/REC-xslt-19991116, and youll find the version 2 working draft at www.w3.org/TR/2005/WD-xslt20-20050211/.

XSLT is much more powerful than CSS; it can convert XML documents into valid XHTML documents for use by search engines and screen readers. XSLT also filters, sorts, and rearranges data. When working with XSLT, XPath expressions identify which part of the document to transform.

XPath

You can see the XPath 1.0 recommendation at www.w3.org/TR/1999/REC-xpath-19991116 . At the time of writing, the working draft for version 2 was at www.w3.org/TR/2005/WD-xpath20-20050211/ .

XPath expressions provide a path to a specific part of an XML document. In a way, XPath expressions are similar to file paths. The path to the document root is specified by a single forward slash ( / ). As we dig into each element in the source tree, element names are separated by a forward slash, for example, /phoneBook or /phoneBook/contact .

This listing shows our simple XML phone book example:

 <phoneBook>   <contactid="1">     <name>SasJacobs</name>     <address>123SomeStreet,SomeCity,SomeCountry</address>     <phone>123456</phone>   </contact>   <contactid="2">     <name>JohnSmith</name>     <address>4AnotherStreet,AnotherCity,AnotherCountry</address>     <phone>456789</phone>   </contact> </phoneBook> 

To refer to the <address> elements, use the following path:

 /phoneBook/contact/address 

In other words, start at <phoneBook> , move to <contact> , and finish at the <address> element. You can also use references relative to the current location.

Two slashes allow you to start the path anywhere in the XML document. The following code snippet specifies all <contact> elements, wherever they are located:

 //contact 

XPath expressions can target a specific element, for example, the first <contact> element.

 /phoneBook/contact[1] 

You can use the text() function to refer to the text inside an element:

 /phoneBook/contact/address/text() 

XPath recognizes wildcards, so we can specify all elements in an XML document by using the asterisk ( * ) character. This example shows all child elements of <phoneBook> :

 /phoneBook/* 

You can refer to attributes with the @ symbol, for example, the id attribute of <contact> :

 /phoneBook/contact/@id 

There is a lot more to the XPath specification than weve covered here, but this will provide a good starting point for the examples that will follow.

XSLT

Many people use the terms XSL and XSLT interchangeably. An XSLT stylesheet is an XML document that contains transformation rules to apply to an XML source document. We call the original XML document the source tree. The transformed document is the result tree . A style sheet is an XML document so you use the same rules for well- formedness .

XSLT style sheets start with a declaration followed by a document root. XSLT documents have a root element of either <stylesheet> or <transform> . We also need to include a reference to the namespace.

 <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

or

 <?xml version="1.0"?> <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

Its more common to use <stylesheet> than <transform> . The closing tag in the style sheet will need to match this declaration.

In the previous examples, the namespace uses the xsl prefix so the elements are written <xsl:stylesheet> or <xsl:transform> . The code that follows also uses the xsl prefix as were working in the same namespace.

Transforming content

XSLT documents can include an <template> and an <output> element. The <template> element shows how to transform the XML elements:

 <xsl:template match = "Xpath expression"> 

The attribute match specifies which elements the template should affect.

The <output> element defines the format for the output document:

 <xsl:output method="html" version="4.0" indent="yes"/> 

We use an XPath expression to target each element or group of elements to be transformed. This listing shows a transformation of the phone book XML document into an HTML document:

 <xsl:template match="/">   <html>   <body>   <h1>Phone Book</h1>   <ul>   <xsl:for-each select="/phoneBook/contact">     <li><xsl:value-of select="name" /></li>   </xsl:for-each>   </ul>   </body>   </html> </xsl:template> 

In the example, the document root is identified and transformed to create the <html> , <body> , and <ul> elements. For simplicity, no DTD or <head> section has been included in HTML in this example.

Each contact creates a <li> element that contains the value of the <name> element.

We can use a for-each statement to work with elements that appear more than once in the XML source document. Its a way to loop through a collection of elements. The example loops through the <contact> elements using the XPath expression /phoneBook/contact as the value of the select attribute.

The value-of statement returns the value of an element so that it can be included with the transformed HTML. In our example, value-of retrieves the value of the <name> element and includes it as a list item. Because the statement is inside a for-each loop, the <name> element uses a relative reference. It is a child of the <contact> element.

Ive saved the complete style sheet as the resource file listStyle.xsl . Its a valid XML document, so you can display it in a web browser as shown in Figure 3-31.

image from book
Figure 3-31: Internet Explorer showing the XSLT file

The following line applies the XSLT style sheet to the source XML document addressXSL.xml . It is included below the XML declaration:

 <?xml-stylesheet type="text/xsl" href="listStyle.xsl"?> 

Figure 3-32 shows the source document displayed in Internet Explorer after the transformation.

image from book
Figure 3-32: The transformed XML file in Internet Explorer

If you have installed the XML tools for Internet Explorer, you can right click the file and choose View XSL Output . It will display the XHTML created by the transformation. You can see this in Figure 3-33. The instructions for downloading the tools are in the section Using XML information in Chapter 2.

image from book
Figure 3-33: The XSL output in Internet Explorer.

Sorting content

You can sort XML documents at the same time that they are transformed. Sorting is only relevant where you have an element that repeats in the XML document. A sort element is added below a for-each element:

 <xsl:for-each select="/phoneBook/contact"> <xsl:sort select="name"/> 

You can specify more than one level of sorting with

 <xsl:sort select="name,address,phone"/> 

The <sort> element allows for other sorting options, such as ascending or descending order :

 <xsl:sort select="name" order="descending"/> 

Filtering content

XSLT transformations can also filter XML documents using XPath expressions. A filter criterion is added to the select attributes in the for-each statement:

 <xsl:for-each select="/phoneBook/contact[name='Sas Jacobs']"> 

This XPath expression uses [name='Sas Jacobs'] to specify which contact should be selected. This is called a predicate . This criterion would only display the contact with a <name> value of Sas Jacobs . You can also use != (not equal to), &lt; (less than), and &gt; (greater than) in filter criteria.

Conditional content

The <if> element is used to conditionally include content in the result tree:

 <xsl:for-each select="/phoneBook/contact">   <xsl:if test="@id&gt;1">     <li><xsl:value-of select="name" /></li>   </xsl:if> </xsl:for-each> 

This example only includes contacts where the id attribute is greater than 1. Notice that I used the entity &gt; to replace the > sign. This is necessary because using the > sign would indicate that the element should be closed.

You can specify alternative treatment for elements using <choose> , as shown here:

 <xsl:for-each select="/phoneBook/contact">   <xsl:choose>     <xsl:when test="@id&gt;1">       <li><xsl:value-of select="name" /></li>     </xsl:when>     <xsl:otherwise>       <li><xsl:value-of select="address" /></li>     </xsl:otherwise>   </xsl:choose> </xsl:for-each> 

This listing uses <when> to test whether the contact attribute id is greater than 1. If so, the value of the <name> element displays. If not, the <otherwise> element specifies that the value of the <address> element should display. Its a nonsensical example, but I think youll get the idea.

An example

XSLT will probably become clearer when we look at another example. Ill use XSLT to transform the phone book XML document into a table layout. The example will sort the XML document into name order. Each contact will display in a new row and the name, address, and phone details in a different cell .

Figure 3-34 shows how each XML element maps to XHTML content.

image from book
Figure 3-34: Mapping elements from the source tree to the result tree

In addition, the transformed content will be styled with a CSS style sheet.

Ive called the completed XSLT file tableStyle.xsl (which youll find in the resource files). The following listing shows the style sheet. Note that Ive simplified the structure of the final HTML document.

 <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:template match="/">     <html>       <head>       <title>Phone Book</title>       <link href="tablestyles.css" type="text/css" rel="stylesheet"/>     </head>     <body>     <h1>Phone Book</h1>     <table>     <tr>       <th>Name</th>       <th>Address</th>       <th>Phone</th>     </tr>     <xsl:for-each select="/phoneBook/contact">     <xsl:sort select="name" />     <tr>       <td><xsl:value-of select="name" /></td>       <td class="shading"><xsl:value-of select="address"/></td>       <td><xsl:value-of select="phone" /></td>     </tr>     </xsl:for-each>     </table>     </body>     </html>   </xsl:template> </xsl:stylesheet> 

The style sheet starts with an XML declaration and a style sheet processing instruction. It indicates a template starting at the root element. The transformation creates the HTML document, a page head, and a title. It also creates a reference to a CSS style sheet called tablestyles.css. Within the body, a table with a row of headings is created.

The transformation sorts each <contact> element by name and displays it in a table row. Table cells are created for the <name> , <address> , and <phone> elements.

The XML document address_tableXSL.xml uses this style sheet. Figure 3-35 shows the transformed file in Internet Explorer.

image from book
Figure 3-35: The transformed XML file in Internet Explorer

Other methods of applying transformations

You can use JavaScript to apply an XSLT transformation. This is an alternative if you dont want to include a reference to an XSLT file in your source XML document. For example, you might consider this if you want the transformations to be browser specific after detecting the browser version.

JavaScript can use the XML DOM of a web browser to transform the source tree. For example, in Internet Explorer, the Microsoft.XMLDOM includes the transformNode method. The following listing loads the XML source document and XSLT style sheet, and uses JavaScript to apply the transformation:

 <script type="text/javascript">   var xmlSourceDoc = new ActiveXObject("Microsoft.XMLDOM");   xmlSourceDoc.async = false;   xmlSourceDoc.load("address_tableXSL.xml");   var xslTransformDoc = new ActiveXObject("Microsoft.XMLDOM");   xslTransformDoc.async = false;   xslTransformDoc.load("tableStyle.xsl");   document.write(xmlSourceDoc.transformNode(xslTransformDoc)); </script> 

Open the resource file transform.htm in a web browser to see the transformation in action. It looks just like the previous example, but we achieved the look in a different way.

You can also use languages like PHP, ASP.NET, and ColdFusion to apply a transformation server-side and deliver formatted XHTML to the web browser.



Foundation XML for Flash
Foundation XML for Flash
ISBN: 1590595432
EAN: 2147483647
Year: 2003
Pages: 93
Authors: Sas Jacobs

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net