XSLT with PHP By Nabil ADOUI, member of the 4D Technical Support team
Contents Summary... 3 Introduction... 3 Important elements... 3 The PHP XSL library... 4 The PHP XSL API... 5 XSLTProcessor:: construct... 5 XSLTProcessor::setParameter... 5 XSLTProcessor::importStylesheet... 6 XSLTProcessor::transformToXML... 6 XSLTProcessor::transformToURI... 6 Demonstration... 7 Error management... 11 Conclusion... 11
Summary In this technical note, we are going to cover the XSL(PHP) extension used to perform XSL Transformations. This extension will replace these 4D commands: XSLT APPLY TRANSFORMATION, XSLT SET PARAMETER and XSLT GET ERROR. Introduction XSLT is a standard defined by W3C. This language transforms an XML file to another type of file (XML, HTML or any other type recognized by the browser) in order to give a more meaningful visual presentation to the original document. Important elements An XSL Transformation receives two elements as input: The XML document that you want to transform An XSL style sheet (XML style sheets). This is an XML file describing the presentation of the contents of our document. It must be declared as follows: <? xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transfor m" version="1.0">... </xsl:stylesheet> Both these files will be used by an XSLT processor based on the PHP XSL library that will replace the XALAN C++ processor currently used by 4D. The result is an XML document that includes the contents of the original document represented according to the specified style sheet.
The PHP XSL library PHP XSL is an implementation of the XSLT standard that uses the libxslt library (XSLT C library for GNOME). It contains a single XSLTProcessor class with a dozen or so methods shown below: XSLTProcessor XSLTProcessor class XSLTProcessor:: construct Creates a new XSLTProcessor object XSLTProcessor::getParameter Returns the value of the parameter XsltProcessor::getSecurityPrefs Returns the security preferences XSLTProcessor::hasExsltSupport Determines whether PHP supports XSLT XSLTProcessor::importStylesheet Imports style sheet XSLTProcessor::registerPHPFunctions Allows the use of PHP functions as XSLT functions XSLTProcessor::removeParameter Deletes a parameter XSLTProcessor::setParameter Sets the value of a parameter XSLTProcessor::setProfiling Sets an output file for a profile XsltProcessor::setSecurityPrefs Sets the security parameters XSLTProcessor::transformToDoc Transforms to a DOM document XSLTProcessor::transformToUri Transforms to a URI XSLTProcessor::transformToXML Transforms to an XML In the remainder of this technical note, we re going to focus on just 5 of these methods: XSLTProcessor:: construct XSLTProcessor::setParameter XSLTProcessor::importStylesheet XSLTProcessor::transformToXML XSLTProcessor::transformToURI
The PHP XSL API XSLTProcessor:: construct This method is simply the constructor of the XSLTProcessor class. It can be used to create a new XSLTProcess type object. It does not accept any parameters or return any values. Signature: XSLTProcessor:: construct ( void) Example call: $xsl = new XSLTProcessor; XSLTProcessor::setParameter This method saves one or more parameters to be used in the transformations that follow it. You can call this parameter in your XSL file using the «$» symbol followed by the parameter name. Signatures: bool XSLTProcessor::setParameter ( string $namespace, string $name, string $value) bool XSLTProcessor::setParameter ( string $namespace, array $options ) $namespace: URI namespace of the XSLT parameter, $name: local name of XSLT parameter $value: new value of XSLT parameter $options: array of name => value pairs Example call: $xsl = new XSLTProcessor(); $xsl->setparameter('', 'param1','value1'); You can also pass an array of parameters:
$params['param1'] = 'value1' ; $params['param2'] = 'value2' ; $xsl->etparameter('http://www.w3.org/1999/xsl/transform', $params); XSLTProcessor::importStylesheet This method imports the style sheet represented by the XSL file that we want to apply during the transformation. Signature: void XSLTProcessor::importStylesheet ( object $stylesheet ) Example: $xsl = new DOMDocument; $xsl->load('xslt2.xsl'); $proc = new XSLTProcessor; $proc->importstylesheet($xsl); XSLTProcessor::transformToXML TransformToXML converts the source document to a text by applying the XSL file imported using the importstylesheet method. Signature: string XSLTProcessor::transformToXML ( DOMDocument $doc ) XSLTProcessor::transformToURI This method transforms the source document to a file that will be saved to the URI specified as a parameter of the method, after applying the chosen style sheet. Signature: int XSLTProcessor::transformToURI ( DOMDocument $doc, string $uri )
Demonstration For our example, we will use the following XML document containing song/album titles and performers, as well as the years they were released: <?xml version="1.0" encoding="utf-8"?> <catalog> <title>empire Burlesque</title> <performer>bob Dylan</performer> <year>1985</year> <title>hide your heart</title> <performer>bonnie Tyler</performer> <year>1988</year> <title>greatest Hits</title> <performer>dolly Parton</performer> <year>1982</year> <title>still got the blues</title> <performer>gary Moore</performer> <year>1990</year> <title>eros</title> <performer>eros Ramazzotti</performer> <year>1997</year> <title>one night only</title> <performer>bee Gees</performer> <year>1998</year> <title>sylvias Mother</title> <performer>dr.hook</performer> <year>1973</year> <title>maggie May</title> <performer>rod Stewart</performer> <year>1990</year> <title>romanza</title> <performer>andrea Bocelli</performer> <year>1996</year> </catalog>
Next we are going to apply an XSL transformation with PHP XSL based on the following style sheet: <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="html" version="4.0" encoding="utf-8" indent="yes"/> <xsl:template match="/"> <html> <body> <h2>my collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>title</th> <th>performer</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <xsl:choose> <xsl:when test="year > $param1"> <td bgcolor="red"><xsl:value-of select="title" /></td> <td bgcolor="red"><xsl:value-of select="performer" /></td> </xsl:when> <xsl:otherwise> <td><xsl:value-of select="title" /></td> <td><xsl:value-of select="performer" /></td> </xsl:otherwise> </xsl:choose> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> This style sheet will group the data of the XML file into a two-column array. To make the task a bit more interesting, we re going to highlight rows where the release year is higher than the ($param1) parameter that we will provide in our PHP code.
So here is our PHP code: <?php $xml = new DOMDocument; $xml->load('xml_file.xml'); // Loading XML document $xsl = new DOMDocument; $xsl->load('xsl_file.xsl'); // Loading style sheet $proc = new XSLTProcessor; // Creating XSLT processor $proc->importstylesheet($xsl); // Attaching XSL rules $proc->setparameter('','param1','1996'); // Inserting $param1 parameter echo $proc->transformtoxml($xml); // Applying transformation?> In this example, we assume that the XML and XSL files are located in the same directory as the source PHP file; otherwise, we would have to provide the complete pathname. On the 4D side, we ll execute this PHP code using the following commands: $filepath:=get 4D folder (Current resources folder)+"php.php" $isok:=php Execute($filePath;"";$res) PHP GET FULL RESPONSE (stdout;errlabels;errvalues;httpheaderfields;httpheadervalues) If ($isok) vhtml:=$res End if The result of the transformation will be saved in the vhtml variable.
After this 4D method is executed, vhtml will contain the following HTML code: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd">\n<html><body>\n<h2>my collection</h2>\n<table border="1">\n<tr bgcolor="#9acd32">\n<th>title</th>\n<th>performer</th>\n</tr>\n<tr>\n<td>empire Burlesque</td>\n<td>Bob Dylan</td>\n</tr>\n<tr>\n<td>Hide your heart</td>\n<td>bonnie Tyler</td>\n</tr>\n<tr>\n<td>Greatest Hits</td>\n<td>Dolly Parton</td>\n</tr>\n<tr>\n<td>Still got the blues</td>\n<td>gary Moore</td>\n</tr>\n<tr>\n<td bgcolor="red">eros</td>\n<td bgcolor="red">eros Ramazzotti</td>\n</tr>\n<tr>\n<td bgcolor="red">one night only</td>\n<td bgcolor="red">bee Gees</td>\n</tr>\n<tr>\n<td>Sylvias Mother</td>\n<td>Dr.Hook</td>\n</tr>\n<tr>\n<td>Maggie May</td>\n<td>Rod Stewart</td>\n</tr>\n<tr>\n<td>Romanza</td>\n<td>Andrea Autrement, vous pouvez utiliser la méthode XSLTProcessor::transformToURI de la manière suivante ; <?php $xml = new DOMDocument; $xml->load('xml_file.xml'); $xsl = new DOMDocument; $xsl->load('xsl_file.xsl'); $proc = new XSLTProcessor; $proc->importstylesheet($xsl); $proc->setparameter('','param1','1996'); echo $proc->transformtouri($xml,'out.html');?> The result will be saved in the «out.html» file next to the PHP code file; however, you can provide another path if you want.
Here is a preview of the result: Error management If an error occurs during the transformation, the error message will be copied into the errvalues variable that was passed in the PHP GET FULL RESPONSE command. Conclusion The PHP XSL library is an excellent tool which can replace the XSLT APPLY TRANSFORMATION, XSLT SET PARAMETER and XSLT GET ERROR commands after their removal. This library provides a rich API allowing you to carry out all the operations necessary for your XSL transformations.