ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 http://www.onlamp.com/pub/a/onlamp/2001/03/16/sablotron.html
 See this if you're having trouble printing code examples


PHP and the Sablotron Processor

by W.J. Gilmore
03/16/2001

Related Articles:

AxKit: An XML-Delivery Toolkit for Apache

XML-RPC: It Works Both Ways


If you need to learn what XSLT is or how to code it, check out these articles from XML.com:

Entities and XSLT

Extensions to XSLT

What is XSLT?

A few months ago, I ran into a dilemma at work. Allow me to retell the story to the best of my recollection....

"Hey W.J., I need a TOD on that PHP-XML-XSL project for that ASP over in NYC!" said my boss.

"How to get this done ASAP?" I thought while wringing my hands. I stared down at my DKNY jeans and my feet propped up in front of my IBM PC.

Other than suffering from acronym overkill, I had another problem. I needed to build a PHP-powered news application that easily converted XML (Extensible Markup Language) into various formats via XSLT (Extensible Stylesheet Language Transformation) so the client could view the content using either a conventional PC browser or a wireless device (a WAP-enabled cellphone for example). Although at the time I was fairly familiar with XML and XSL syntax, I was having a hard time figuring out exactly how to perform the conversions into the style formats I wanted. That is, until I found one of PHP's newest extensions: the Sablotron processor.

The Sablotron XSLT processor, a product of Ginger Alliance Ltd. out of the Czech Republic, has recently been incorporated into PHP's already vast extension library. Sporting a number of useful functions, it makes basic XSL transformations a snap. In this article, I'll introduce you to this tool, and show you how I ended up building the news application with minimal time and effort. Let's begin with a brief overview of Sablotron and its configuration process as it relates to PHP.

PHP and the Sablotron processor

Sablotron is an expat-based XSLT processor written in C++, which allows for greater portability across platforms. This suits PHP just fine, and it runs great as a PHP extension on both Windows and non-Windows platforms. Take a moment to review the configuration information relevant to your platform:

Non-Windows configurations
To make use of the Sablotron extension with your non-Windows PHP distribution, you'll need to configure PHP with the flag --with-sablot. If you aren't exactly sure how to build extensions into your non-Windows PHP distribution, I strongly suggest checking out Darrel Brogdon's excellent article, Basic Installation of PHP on a Unix System.

Windows configurations
The Win32 binaries available via the PHP site come with the Sablotron extension already built in. Therefore, upon downloading, installing, and configuring the most recent Win32 distribution, open up your php.ini file and uncomment the line:

;extension=php_sablot.dll

Uncommenting the line simply involves removing the semicolon.

Platform-independent configuration procedures

Regardless of the platform, there is another configuration step that you need to perform. Due to the fact that XML and PHP share a common page-structure property -- both use the <?...?> escape tag -- you won't be able to use the short tags format to escape to a PHP document. Instead, you can choose from the three other accepted escape formats PHP allows. The most common way to do this is:

<?php

print "hello world!";

?>

Click here to review all allowed forms of escape syntax.

Incidentally, you could ensure that the short tags style is never used within a PHP document by modifying your php.ini file. If you are interested in doing so, open up php.ini and find the line:

short_open_tag = On

This basically says that it's okay for you to use the short tags when escaping to and from a PHP document. To disallow the short tags style, change this configuration directive to read:

short_open_tag = Off

Okay, your configuration is done. Let's move on to the fun stuff: XSLT!

The Sablotron transformation process

If you've ever worked with file handles in any language, you'll find that performing XSL transformations with the Sablotron processor to be a familiar process. Allow me to break this process down into five generalized steps:

  1. Create a new XSL processor handle.
  2. Read in the respective XML and XSL documents.
  3. Perform the XSL transformation.
  4. Output the XSL transformation to the requesting client.
  5. Free up the allocated XSL resources.

Of course, this generalized process is not specific to the Sablotron processor; this scheme is common in many XSLT processors. Furthermore, this assumes that the intent is to immediately output the content to the device instead of perhaps storing it to a database or performing further functions. However, for sake of introducing the extension, this process flow will work just fine.

Now that you have an idea of the general scheme of events that will take place in the news application, I'll turn my attention toward the project. In the next section, I'll show you how I created my news application using the Sablotron extension.

The news application

The goal of the news application is to create a mechanism for parsing an XML file and transforming it into a format recognizable by either a conventional PC browser or a typical WAP-enabled wireless device. Although the PHP script is relatively short, I've incorporated a few features (device detection, for example) that make it particularly useful. It's also basic enough that you could swipe the code and perform modifications as necessary. Before delving into the code, I'll outline a typical scenario that would involve the script:

  1. User sends request to view the company news.
  2. The Web server hosting the news application recognizes the request, and calls upon the PHP script to perform the necessary actions.
  3. The PHP script sniffs for the browser type, and can thus determine the type of device using that browser. For sake of simplicity, I'll keep this rather abbreviated in terms of browser types.
  4. The script performs the XSL transformation in accordance with the requested transformation format.
  5. The resulting transformation is sent back to the requesting client.

Sounds pretty straightforward, right? In fact, it is. Of course, the first two steps of this process are out of the scope of the PHP script, since they relate to the Web server. Before moving on to step 3, I'll present the actual XML and XSL documents that are used in the news application. Listing 1-1 contains the XML document, titled news.xml, and listings 1-2 and 1-3 contain the XSL transformation documents for the PC browser (pcnews.xsl) and WAP browser (wapnews.xsl), respectively.

Listing 1-1: The news.xml document

<?xml version= "1.0">
<news xmlns:news="news.dtd">
<newsitem>
<title>PHP 4.04 is released!</title>
<submissionDate>December 19, 2000</submissionDate>
<author>PHP development team</author>
<story>To the chagrin of bewildered rivals, PHP 4.04 was released today.
Several bug fixes and enhancements to both the core and many extensions
are included in the release.</story>
</newsitem>
<newsitem>
<title>A Programmer's Introduction to PHP 4.0 is available!</title>
<submissionDate>January 5, 2001</submissionDate>
<author>W.J. Gilmore</author>
<story>In a shameless plug for himself, W.J. Gilmore announces the
official publishing date of his PHP textbook. Get your copy while it's
hot!</story>
</newsitem>
<newsitem>
<title>PHP: A benefit to the environment?</title>
<submissionDate>January 15, 2001</submissionDate>
<author>Greenpeace</author>
<story>In what's being hailed as one of the breakthrough discoveries of
the 21st century, scientists announced today that since PHP's inception
in 1995, the ozone hole has actually shrunk by 34 percent. Could there be a
direct correlation here?</story>
</newsitem>
</news>

Listing 1-2: The pcnews.xsl document

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="utf-8"/>

<xsl:template match="/ledger">
<html>
<head>
<title>What's new in programming?</title>
</head>
<body bgcolor="#ffffff" text="#000000" link="#808040"
vlink="#000000" alink="#606060">
<table bgcolor="white" border="0" cellpadding="2" cellspacing="2">
<xsl:call-template name="newsitems"/>
<table>
</body>
</html>
</xsl:template>

<xsl:template name="newsitems">
<xsl:for-each select="newsitem">
<tr><td>
<b><xsl:value-of select="title"/></b><br/>
Date: <xsl:value-of select="submissionDate"/><br/>
Submitted by: <xsl:value-of select="author"/><br/>
<xsl:value-of select="story"/><br/>
</td></tr>
</xsl:for-each>
<xsl:template>

</xsl:stylesheet>

Listing 1-3: The wapnews.xsl document

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="utf-8"/>

<xsl:template match="/ledger">
<wml>
<card id="card1" title="News">
<xsl:for-each select="newsitem">
<p>
<b><xsl:value-of select="title"/></b><br/>
<xsl:value-of select="submissionDate"/><br/>
<xsl:value-of select="author"/><br/>
<xsl:value-of select="story"/><br/>
</p>
</xsl:for-each>
</card>
</wml>
</xsl:template>
</xsl:stylesheet>

Listing 1-4 illustrates how the requesting browser type can be detected and how the determination of device type can be assumed as a result of this detection. This detection method is rather simple, since it only distinguishes those user agents sent by Nokia, Ericsson, and Phone.com (the UP.SDK browser) to make up the family of WAP browsers. However, you can easily add to this list as necessary. Furthermore, the function determines that anything not considered to be a WAP browser must be HTML, which is also not necessarily the case, since it discounts devices such as PDAs and pagers.

Listing 1-4: A simple browser/device detector (xmllib.inc)

function DeviceType() {

$browser_array = array("Noki", "Eric", "UP.B");
$browser = substr( trim ($HTTP_USER_AGENT), 0, 4);

if (in_array($browser, $browser_array)) :

$xsltFile = "wapnews.xsl";

else :

$xsltFile = "pcnews.xsl";

endif;

return $xsltFile;

} // end DeviceType()

The final and perhaps most important piece of code is shown in Listing 1-5. This is the PHP code that calls the Sablotron functions that perform the XSL transformation.

Listing 1-5: The PHP/Sablotron script (transform.php)

<?php

// Include the DeviceType() function.
INCLUDE("xmllib.inc");


// What are the XML and XSL files?
$xmlFile = "news.xml";
$xslFile = DeviceType();

// Create a new processor handle
$th = @xslt_create() or die("Can't create XSLT handle!");

// Open the XML and XSL files
$xh = fopen($xmlFile, "r") or die("Can't open XML file");
$sh = fopen($xslFile, "r") or die("Can't open XSL file");

// Read in the XML and XSL contents
$xmlContent = fread($xh, filesize($xmlFile));
$xslContent = fread($sh, filesize($xslFile));

// Perform the XSL transformation
@xslt_process($xslContent, $xmlContent, $XSLtransformation);

// send the correct WAP header if necessary
if ($xslFile == "wapnews") :

header("content-type: text/vnd.wap.wml");

endif;

// Output the transformed XML file
echo $XSLtransformation;

// Free up the resources
@xslt_free($th);

?>

That's all there is to it! After executing Listing 1-5 using the news.xml and pcnews.xsl documents, you will see an output very similar to the one shown in Figure 1.

Screenshot of resulting output.
Figure 1. News.xml transformed using pcnews.xsl.

Figure 2 displays how news.xml might look in the typical WAP browser. In this example, I used Phone.com's UP.SDK browser.

Results viewed with a WAP browser.
Figure 2. news.xml transformed using wapnews.xsl

Conclusion

There's no doubt about it, the Sablotron extension is awesome. Using it, XSL transformations are a snap. If you end up doing anything cool with it, please send me your feedback; I'd love to hear about it.

W.J. Gilmore has been developing PHP applications since 1997, and is frequently published on the subject within some of the Web's most popular development sites. He is the author of 'A Programmer's Introduction to PHP 4.0' (January 2001, Apress), and is the Assistant Editorial Director of Web and Open Source Technologies at Apress.


Return to ONLamp.com.

Copyright © 2007 O'Reilly Media, Inc.