Trading Systems Analyst (IL)
Next Step Systems
US-IL-Chicago

Justtechjobs.com Post A Job | Post A Resume

Using XML: A PHP Developer's Primer, Part 3
In our last article, we touched the surface of Ajax by developing a simple email validation application. In this article we are going to delve deeper into Ajax and explore how XSL can be used on both the client side (using Javascript) and on the server (using PHP) to transform XML data into XHTML.

eXtensible Stylesheet Language (XSL)
XSL is an application of XML that is used to describe the presentation of XML through the use of stylesheets. It is similar to CSS, however, it is generic enough to be applied to any type of XML data.

Although originally created to format XML documents for visual display, XSL has found another niche: XSL-Transformations (XSLT). XSLT is used to transform an XML document into another XML document. It can make subtle changes to the document, or it can completely rearrange the order and structure of the data. One of the common uses of XSLT is to convert XML to XHTML or HTML.

XSL uses the xPath language (introduced in my previous article) to navigate through the XML document. The templates, iterative loops and conditionals all use xPath expressions to select the necessary data.

The XSL Namespace – (a brief introduction to XML namespaces)
Namespaces allow two different types of XML to co-exist in the same document. As XSL is a an application of XML which is used to transform different XML formats, it is quite probable that the stylesheet will contain more than one type of XML. Therefore, XSL uses the its own namespace. A namespace can be declared in any element and affects all its children. In XSL, it is declared in the root (<xsl:stylesheet>) element.

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


The namespace declaration takes the following format:

xmlns:ns="uri"


ns = the namespace identifier. Any element name prefixed with ns will fall into this namespace.
uri = this is the namespace URI. It can be anything you like as long as it is unique within the context of the document. Authors often use this to point to information about the XML format on the Internet.

For more information about XML namepaces, you can find the full documentation on the w3c website. All XSL tags must be prefixed with the xsl namespace prefix, otherwise they will be ignored.

A simple XSL Stylesheet
To demonstrate XSLT, we first need an XML file to use as input. We will be using the library XML example seen in the first part of the series. A few modifications, however, have been made to the book definitions. Among these, we have added the ISBN number as an attribute to uniquely identify each book and we have separated the authors into their own separate list.

<library>
    <categories>
        <category id="1">Category Name</category>
    </categories>
    <authors>
        <author id="1">Author Name</author>
    </authors>
    <book isbn="0471777781" hascover="yes
">
        <title>Professional Ajax</title>
        <publisher>Wrox</publisher>
        <category>3</category>
        <category>6</category>
        <author>7</author>
        <author>8</author>
        <author>9</author>
        <synopsis>
            Combining tried-and-true CSS, XML and Javascript technologies, Ajax provides web developers with the
            ability to create more sophisticated and responsive user interfaces and break free from the
            &quot;click-and-wait&quot; standard that has dominated the web since its introduction.
        </synopsis>
    </book>
</library>

The full XML file can be found in the ZIP file accompanying this article.
A Simple XSL Stylsheet
This XSL stylesheet when applied to the library XML, transforms it to XHTML.

XSL:
<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   
    <!-- the output method can be text | xml | html !-->
    <xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8"
            doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
            doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
        />
    <!-- start with matching the root of the XML -->
    <xsl:template match="/library">
        <html>
            <head>
                <title>XML Library</title>
            </head>
            <body>
                <!-- the apply-templates attribute applies all other XSL templates to direct descendants of the currently
                     selected node. Some XSL processors spit out text if no template exists for a given descendant, therefore
                     an xPath expression is used to select only the nodes we want transformed -->
                <xsl:apply-templates select="books/book">
                    <!-- the XSL to match each book element is held in a separate template
                         purely to aid in readability of the stylesheet !-->
                    <xsl:sort select="title" /> <!-- sort the list by book title -->
                </xsl:apply-templates>
            </body>  
        </html>
    </xsl:template>   
    <xsl:template match="book">
        <!-- variables are used as they can be embedded inside xPath expressions and HTML attributes -->
        <xsl:variable name="isbn" select="@isbn" />
        <xsl:variable name="title" select="title" />
        <xsl:variable name="hascover" select="@hascover" />
        <div>
            <hr />
            <!-- here we extract the value of a single element which contains a single text node -->
            <h2><xsl:value-of select="$title" /></h2>
            <hr />
            <!-- below, an xsl:if test ensures we only display the cover if the havcover attribute of the book
                 tag is set to yes -->
            <xsl:if test="$hascover = 'yes'">
                <img alt="{$title}" src="../book_covers/{$isbn}.jpg" />
            </xsl:if>
            <p><xsl:value-of select="synopsis" /></p>
            <h3>Categories</h3>
            <ul>
                <!-- we could have use for-each to similar to the one used below to iterate through the book
                     elements instead of a template -->
                <xsl:for-each select="category">
                    <!-- in XSL, we use "." to extract the value of the current element and store its value
                         in a variable called cid -->
                    <xsl:variable name="cid" select="." />
                    <!-- the xPath expression here extracts the category name from the category list
                           based on the value stored in the cid variable -->
                    <li><xsl:value-of select="/library/categories/category[@id=$cid]" /></li>
                </xsl:for-each>
            </ul>
            <h3>Authors</h3>
            <ul>
                <xsl:for-each select="author">
                    <xsl:variable name="aid" select="." />   
                    <li><xsl:value-of select="/library/authors/author[@id=$aid]" /></li>
                </xsl:for-each>
            </ul>
            <p><b>Publisher:</b> <xsl:value-of select="publisher" /></p>
            <p><b>ISBN: </b> <xsl:value-of select="$isbn" /></p>
        </div>
    </xsl:template>
</xsl:stylesheet>

Although the structure of XSL is quite self-explanatory, here are a few important points to observe:
  • Notice the doctype-system and doctype-public attributes in the xsl:output element. This ensures the output is valid XHTML.

  • The xPath expressions which appear in select, match and test attributes are evaluated in the context of the currently selected element. Therefore the following expression takes the value of the current category element selected, within the xsl:for-each iteration.

    <xsl:variable name="cid" select="." />

  • XSL variables are used where the value is to be included as part of the xPath expression or inside an HTML attribute. The declaration takes the following form:

    <xsl:variable name="title" select="title" />

    Inside xPath expressions, variables are prepended with a dollar:

    <h2><xsl:value-of select="$title" /></h2>

    Inside XML/HTML attributes they are additionally enclosed in curly brackets:

    <img alt="{$title}" src="book_covers/{$isbn}.jpg" />

  • The first xsl template must contain an xPath expression that matches relative to the root of the XML document element <library>
  • The xsl:apply-templates element matches only books elements. This ensures that the transformer does not attempt to transform the category and author lists.
Having created a style sheet, applying it to the XML does not require any code. Internet Explorer 6 and Firefox can both transform an XML document which contains an xml-stylesheet declaration:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="book_summary.xsl" ?>
<library>



Comments:

No Messages Found

You can post questions/corrections/feedback here

 

If you are looking for help, please post on the appropriate forum here. Your questions will be answered much more quickly.

Add A Comment:

Name:

Email:

Subject:

Message:

To reduce spam posts, messages are now manually approved

You are not [logged in]. That means your account will not get credit for this post.