#native_company# #native_desc#
#native_cta#

Using XML: A PHP Developer’s Primer, Part 3

By PHP Builder Staff
on April 9, 2012

XSLT in PHP
Like XML, PHP 4 provides the XSLT extension, while PHP 5 provides the W3C compliment XSL extension. We will focus here on PHP 5’s implementation of the XSL extension. Before using XSL, it must be enabled and the required libraries must also be installed on the host operating system.

Installation

Windows
To check whether or not XSL is already enabled on a server, create a file which calls the phpinfo() function and check for the XSL section.
On Windows, XSL support requires two dll files.

    * libxslt.dll, which should be in the root PHP installation directory. This file can be obtained from zlatkovic.com
    * php_xsl.dll, which should be inside the extension directory as set in the extension_dir directive in php.ini

To enable XSL support, add or uncomment the following line in the php.ini file:

extension=php_xsl.dll

Unix
On Unix platforms, the XSL extension needs to be enabled at compile time and requires the libxslt libraries from xmlsoft to be installed. After obtaining the source code from xmlsoft, extract it and follow the familiar configure, make, make install, routine to install them:

# tar xvf libxslt-1.1.2.tar.bz2 -–bzip2
# cd libxslt-1.1.2
# ./configure
# make
# su -c “make install”

Finally, we need to recompile PHP enabling the XSL extension:

# cd php-5.1.2
# ./configure –-with-xsl=/path/to/libxslt-1.1.2
# make
# su -c “make install”

Transforming XML with PHP
Transforming an XML document generally requires the following steps:

   1. load the XSL stylesheet into a DOMDocument object.
   2. create an instance of an XSLTProcessor object
   3. import the DOMDocument containing the style sheet into the XSLTProcessor
   4. load the XML document to be transformed into a DOMDocument object
   5. transform the XML

PHP – book_summary.php:
<?php
// 1) load the XSL style sheet into a DOMDocument object.
$xsl = new DOMDocument;
$xsl->load(‘xml/book_summary.xsl’);

// 2) create an instance of an XSLTProcessor object
$processor = new XSLTProcessor;

$processor->setParameter(”, ‘script-path’, $_SERVER[‘PHP_SELF’]);
$processor->setParameter(”, ‘select-isbn’, @$_GET[‘isbn’]);

// 3) import the DOMDocument containing the style sheet into the XSLTProcessor
$processor->importStyleSheet($xsl);

// 4) load the XML document to be transformed into a DOMDocument object
$xml = new DOMDocument(‘1.0’);
$xml->load(‘xml/library.xml’);

// 5) transform the XML
$transformedXml = $processor->transformToXml($xml);

echo($transformedXml);
?>

The transformToXml method transforms the XML using the imported stylesheet, returning the string representation of the transformed XML. Similarly, the transformToDoc function can be used if you require a DOMDocument representation of the transformed XML.

Using XSLT to transform XML makes the code cleaner and allows for clear separation between processing logic and display logic. It also serves to provide a robust way of describing the transformation in a multi-platform, multi-language environment. As we will discover later, we can apply the same XSL stylesheet to the XML using Javascript too.
Passing Variables to an XSL Stylesheet
One of the most powerful features of XSL is its ability to receive variables from external entities which can be used anywhere in the stylesheet. In XSL, an external variable is declared using the xsl:param element as follows:

    <xsl:param name=”select-isbn” />

The current XSL stylesheet lists all books with details accompanying each one. By adding an external variable and making a slight change to the template we can display information on only one specific book, based on a variable passed in the query string containing the ISBN number. A second external variable called script-path will also be added, which contains the URI of the current script.

We need only change the root template. Notice how we now use xsl:for-each to iterate the book list and display the detailed book information at the bottom using the book template:

XSL:    
<xsl:param name=”select-isbn” />
    <xsl:param name=”script-path” />
        <!– start with matching the root of the XML –>
    <xsl:template match=”/library”>
        <html>
            <head>
                <title>XML Library</title>
            </head>
            <body>
                <ul id=”bookList”>   
                <xsl:for-each select=”books/book”>
                    <xsl:sort select=”title” />
                    <xsl:variable name=”isbn” select=”@isbn” />
                    <li>
                    <a href=”{$script-path}?isbn={$isbn}”>
                        <xsl:value-of select=”title”/>
                    </a>
                    </li>
                </xsl:for-each>
                </ul>
                <!– 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 –>
                  <xsl:apply-templates select=”books/book[@isbn=$select-isbn]” />
            </body>  
        </html>
</xsl:template>   

The variable’s values can be passed to the XSL stylesheet using the setParameter function. The next time an XML document is transformed, these variables will be available inside the stylesheet:

$processor->setParameter(”, ‘script-path’, $_SERVER[‘PHP_SELF’]);
$processor->setParameter(”, ‘select-isbn’, htmlentities(@$_GET[‘isbn’]));

The first function parameter sets the namespace URI for the parameter. This can be left as a zero length string when using the default XSL namespace.

XSLT in Javascript
At the time of writing only Internet Explorer and Firefox have support for XSL transformations. Where possible we should take advantage of this and allow the transformations to be carried out on the client side. This not only saves processing time on the server; the XML which is to be transformed is often smaller in size than its HTML counterpart meaning bandwidth savings too. Both Firefox and Internet Explorer have quite different implementations of XSLT.

Firefox
The Firefox XSLT implementation is very similar to PHP’s, as, it too is W3C compliment. In Javascript, we must code more defensively, as we will be acquiring the XML to be transformed and the XML stylesheet via an HTTP connection.

The first step is to load the XSL stylesheet into a DOMDocument. This is achieved with the createDocument function:

var oXsl = document.implementation.createDocument(”, ”, null);
oXsl.async = false;
oXsl.load(‘book_summary.xsl’);

Notice how we deliberately set async to false here. If you intend to load the stylesheet while the page is loading, it is best to use a synchronous request. If you wish to use an asynchronous request, the DOMDocument fires the onload event handler once the XML document has loaded completely.

Before continuing, it is wise to check that the XSL stylesheet has been loaded properly. We can do this by testing the root element of the XML document. If an error occurred while loading the XML document, this will be replaced with a <parsererror> tag:

if ((!oXsl .documentElement) || (oXsl .documentElement.tagName == ‘parsererror’)) {
    /* an error occurred while loading the document */       
}

Once we have confirmed that the stylesheet has been loaded correctly, we can import it as a stylesheet and transform it in exactly the same way as PHP:

var oXslt = new XSLTProcessor();
oXslt.importStylesheet(oXslt);

var oTransformedDom = bookInfoXsl.transformToDoc(oXmlDom);

1
|
2
|
3
|
4