par Alexandre Alapetite le 2004-09-12 ; mise à jour 2008-11-01

Transition du XSL de PHP4 xslt à PHP5 xsl

Lors de l’évolution de PHP4 à PHP5, un certain nombre de modifications sont nécessaires dans les scripts. En PHP4, pour gérer du XSL, il fallait utiliser l’extension xslt, qui était expérimentale. En PHP5, cette extension a été remplacée par l’extension xsl, toujours expérimentale.

La migration du code de PHP4 à PHP5 ne pose pas trop de difficultés, mais peut être longue si xslt a été largement utilisé. De plus, afin de faire une transition en douceur, il est souhaitable que les scripts soit le plus vite possible compatibles PHP5 alors même que le serveur tourne encore en PHP4. L’optimisation des scripts pour PHP5 pourra se faire plus tard.

Je propose sur cette page un module à inclure dans vos scripts PHP/XSLT, pour assurer une certaine compatibilité vers PHP5/XSL.

Pour DOMXML/DOM, regardez ma page PHP4/DOMXML vers PHP5/DOM.

English

Sommaire

Quitter

Scripts PHP4 xslt compatibles PHP5 xsl

Afin de faire marcher vos scripts PHP4 utilisant xslt sur un serveur migrant vers PHP5, il vous suffit d’inclure le fichier xslt-php4-to-php5.php dans vos sources PHP4 de cette manière :

if ((PHP_VERSION>='5')&&extension_loaded('xsl'))
 require_once('xslt-php4-to-php5.php');

Notez que cela ne modifie rien aux scripts lorsque le serveur est encore avec PHP4.
Seulement quelques fonctionnalités les plus courante de xslt sont supportées, mais pas son ensemble. Cela peut néanmoins être étendu si nécessaire.
Ci-dessous, un exemple puis le code du fichier assurant la compatibilité.

exemple-php4.php

<?php
//Code PHP4 utilisant l'extension xslt
//On veut le faire marcher sous PHP5 avec xsl
<?php
if ((PHP_VERSION>='5')&&extension_loaded('xsl'))
 require_once('xslt-php4-to-php5.php'); //Charge le convertisseur si PHP5

$xml='<?xml version="1.0" encoding="ISO-8859-1"?>
<myRoot>
 <myNode/>
 <myNode/>
</myRoot>';

$xsl='<?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="xml" version="1.0" encoding="ISO-8859-1" omit-xml-declaration="no" indent="yes"/>
 <xsl:param name="myParam"/>
 <xsl:template match="/">
  <myRoot2>
   Transformation
   <xsl:apply-templates select="/myRoot/myNode"/>
  </myRoot2>
 </xsl:template>
 <xsl:template match="/myRoot/myNode">
  <myNode>
   <xsl:attribute name="value">
    <xsl:value-of select="$myParam"/>
   </xsl:attribute>
  </myNode>
 </xsl:template>
</xsl:stylesheet>';

$xh=xslt_create();

echo xslt_process($xh,'arg:/_xml','arg:/_xsl',null,
 array('/_xml'=>$xml,'/_xsl'=>$xsl),
 array('myParam'=>'My parameter value'));

/*Output:
<?xml version="1.0" encoding="ISO-8859-1"?>
<myRoot2>
 Transformation
 <myNode value="My parameter value"/>
 <myNode value="My parameter value"/>
</myRoot2>
*/
?>
xslt-php4-to-php5.php

<?php
/*
 Nécessite PHP5, utilise l’extension XSL (à activer)
 Pour être utilisé dans des scripts PHP4 utilisant l’extension XSLT (à activer)
 Permet aux scripts PHP4/XSLT de fonctionner avec PHP5/XSL
 http://alexandre.alapetite.fr/doc-alex/xslt-php4-php5/
*/

$xslArgs=null; //Attention : un seul XSLT à la fois
function xslt_create() {return new xsltprocessor();}
function xslt_errno($xh) {return 7;}
function xslt_error($xh) {return '?';}
function xslt_fetch_result($xslt_handle,$buffer_name=null)
{
 global $xslArgs;
 if (empty($buffer_name)) return $xslArgs['/_result'];
 elseif (substr($buffer_name,0,5)==='arg:/') $buffer_name=substr($buffer_name,5);
 if (isset($xslArgs['/'.$buffer_name])) return $xslArgs['/'.$buffer_name];
 elseif (isset($xslArgs[$buffer_name])) return $xslArgs[$buffer_name];
 else return '';
}
function xslt_free($xh) {unset($xh);}
function xslt_process($xh,$xmlcontainer,$xslcontainer,$resultcontainer=null,$arguments=array(),$parameters=array())
{//Voir aussi : http://alexandre.alapetite.fr/doc-alex/domxml-php4-php5/
 //Basé sur : http://www.php.net/manual/book.xsl.php#45415
 $xml=new DOMDocument();
 $basedir=$xh->getParameter('sablotron','xslt_base_dir');
 if ($basedir && ($workdir=getcwd())) chdir($basedir);
 if (substr($xmlcontainer,0,5)==='arg:/')
 {
  $arg=substr($xmlcontainer,5);
  if (isset($arguments['/'.$arg])) $xml->loadXML($arguments['/'.$arg]);
  elseif (isset($arguments[$arg])) $xml->loadXML($arguments[$arg]);
 }
 else $xml->load($xmlcontainer);
 $xsl=new DOMDocument();
 if (substr($xslcontainer,0,5)==='arg:/')
 {
  $arg=substr($xslcontainer,5);
  if (isset($arguments['/'.$arg])) $xsl_=&$arguments['/'.$arg];
  elseif (isset($arguments[$arg])) $xsl_=&$arguments[$arg];
  else $xsl_='';
 }
 else $xsl_=file_get_contents($xslcontainer);
 $xsl->loadXML(str_replace('arg:/','arg://',$xsl_));
 $xh->importStyleSheet($xsl);
 global $xslArgs;
 $xslArgs=$arguments;
 if ($parameters!=null)
  foreach ($parameters as $param=>$value)
   $xh->setParameter('',$param,$value);
 $result=$xh->transformToXML($xml);
 if (isset($resultcontainer))
 {
  if (substr($resultcontainer,0,4)==='arg:') $xslArgs[substr($resultcontainer,4)]=$result;
  else file_put_contents($resultcontainer,$result);
 }
 if ($basedir && $workdir) chdir($workdir);
 if (isset($resultcontainer)) return true;
 else return $result;
}
function xslt_run($xh,$xslt_file,$xml_data_file,$result=null,$xslt_params=array(),$xslt_args=array()) {return xslt_process($xh,$xml_data_file,$xslt_file,$result==null?'arg:/_result':$result,$xslt_args,$xslt_params);}
function xslt_set_base($xh,$base) {$xh->setParameter('sablotron','xslt_base_dir',str_replace('file://','',$base));}
function xslt_set_encoding($xh,$encoding) {$xh->setParameter('sablotron','xslt_encoding',$encoding);} //Si cela ne fait rien : encodage manuel, ou utiliser xsl:output @encoding dans le document XSL
function xslt_set_error_handler($xh,$handler) {}

class xslt_arg_stream
{
 public $position;
 private $xslArg;
 function stream_eof() {return $this->position>=strlen($this->xslArg);}
 function stream_open($path,$mode,$options,&$opened_path)
 {
  $this->position=0;
  $url=parse_url($path);
  $varname=$url['host'];
  global $xslArgs;
  if (isset($xslArgs['/'.$varname])) $this->xslArg=&$xslArgs['/'.$varname];
  elseif (isset($xslArgs[$varname])) $this->xslArg=&$xslArgs[$varname];
  else return false;
  return true;
 }
 function stream_read($count)
 {
  $ret=substr($this->xslArg,$this->position,$count);
  $this->position+=strlen($ret);
  return $ret;
 }
 function stream_tell() {return $this->position;}
 function url_stat() {return array();}
}

stream_wrapper_register('arg','xslt_arg_stream');
?>

Historique

0.6 2008-11-01
Ajout : xslt_fetch_result(), xslt_run() (compatibilité PHP 4.0.3 à 4.0.6)
Modification : le nom des arguments transmis par arg:/test peut être ensuite référencé avec ou sans slash (/test ou test)
0.5 2006-08-06
Correction : déclaration des attributs de classes selon la syntaxe objet PHP5. Compatible E_STRICT
Ajout : xslt_set_encoding() mais sans effet
0.4 2005-08-28
Ajout : xslt_set_base()
0.3.1 2004-11-23
Licence Creative Commons version française "CC BY-SA (FR)"
0.3 2004-10-30
Correction : protocole file:// (Testé avec PHP 5.0.2)
2004-09-15
Ajouts : domxml_xslt dans la librairie PHP4/DOMXML vers PHP5/DOM.
0.2 2004-09-13
Correction : protocole file://
0.1 2004-09-12
Distribution initiale

Licence

Ce contenu est protégé par une licence Creative Commons Paternité - Partage des Conditions Initiales à l’Identique 2.0 France "BY-SA (FR)" [Creative Commons License]


Commentaires

object : Voir les commentaires

http://alexandre.alapetite.fr

Retour