Transforming XML using XSLT

XSLT is an XML-based language that allows you to manipulate XML documents before outputting them, and PHP implements XSLT processing through the use of the Sablotron library.

When I say that XSLT manipulates XML, it actually transforms it (hence the T in XSLT) into another form. With one XML document, you can make the same content look vastly different - for example, you could parse it with a WML XSL stylesheet and send it to WAP devices, or parse it with an SQL XSL stylesheet and send it to a database.

Several browsers (most notably Microsoft Internet Explorer) can perform XSL transformation on the client-side. It downloads an XML document, the XSL stylesheet, and any accompanying CSS files, then combines them all together on your visitor's computer. But what happens when someone with an old version of IE or any other non-XSL-enabled browser visits your site? They would not see what you wanted them to see, that is for sure!

This is where PHP comes in. Your visitor enters a URL as per usual, and gets to a PHP page on which you have XML/XSL interaction going on. PHP loads the XML and the XSL, combines the two together into the output, and sends that output to the user (often in XHTML format). On the client-side, users see nothing special, no XML or XSL at all, just normal XHTML. Of course, there is nothing stopping that PHP page from analyzing the visitor's user agent and sending content fit for that browser, whether it be HTML 2, XHTML, WAP, or anything else.

Often, XSLT makes more sense once you see it in action, so here's an example XSL document designed to work on the example XML document given previously. Save it in the same directory, as input.xsl:

<?xmlversion="1.0"encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/">
    <xsl:output method="html" indent="no" encoding="utf-8"/>

    <xsl:template match="/">
        <html>
        <head>
        <title>XSLT</title>
        </head>
        <body>
    
        <xsl:for-each select="/channel/item">
            News Item: <xsl:value-of select="title"/><br/>
        </xsl:for-each>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Line 1: <?xml version="1.0" encoding="utf-8" ?>: You should be used to this; it is just the document type. Remember, XSL is an XML language, so it requires this.

Line 2: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/">: This defines what namespaces you will be using in this stylesheet. If you are unfamiliar with namespaces, think of them as vocabulary qualifiers. For example, "<jackrussell>" could be a dog or a person's name, whereas "<dog:jackrussell>" is defined as a specific type of jackrussell. Line 2 in the example XSL defines what namespaces are in use, and where they can be found online for reference.

Line 3: <xsl:output method="html" indent="no" encoding="utf-8"/>: lets you define various output attributes. Here, for example, we are saying that our target is HTML, amongst other things.

Line 4: <xsl:template match="/">: This is a key piece of markup in XSL. XSL uses its "match" attribute to pattern match XML elements. If it finds a matching XML element, the contents of the template are parsed. The pattern matching syntax is not anything you will find elsewhere because it is very specific to matching markup. In the example, we match "/", which equates to the root element. As you have a root element (""), that element is matched, and the contents of the template (, etc) are processed.

Lines 5-9: <html>...<body>: As these aren't XSL processing instructions, Sablotron considers them as output, and no processing is performed here.

Line 10: xsl:for-each is basically an array iterator, like the PHP construct foreach. Here, the array is whatever XML elements are found by pattern matching against the "select" attribute of the for-each. The pattern matching here is the same as used in xsl:template, although this time you are matching against elements that are children of elements. The for-each iterates through every element matching the criteria (there are three in the example) and processes the contents of the for-each once for every matching element.

Line 11 to end: These are closing tags, to ensure you remain XHTML compliant. Remember, you must always close tags you open!

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Adding PHP to the mix >>

Previous chapter: Outputting XML

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.