Utilisant l'extension XSL de PHP 5 pour effectuer des Transformations XSL

Ce tutorial est destiné aux développeurs qui désirent savoir comment générer des documents HTML en utilisant une combinaison de données XML et des feuilles de style XSL. Elle inclut des exemples d'utilisation des paramètres XSL et inclus les feuilles de style.


PHP et XML

Le processus de combiner le contenu d'un fichier XML et les instructions de mise en forme d'un fichier XSL pour produire un autre document est connu sous le nom de : Transformation XSL ( ou XSLT). 

 

Ce tutorial montre comment intégré de PHP module XSL peut être utilisée pour effectuer des transformations XSL. Il montre également comment passer des paramètres optionnels à la feuille de style XSL au cours du processus de transformation et comment vous pouvez utiliser incluent des fichiers pour contenir des définitions de feuille de style partagé.

 

Tandis que les fichiers XSL sont statiques dans des fichiers XML de nature peuvent être créés à la volée"pour contenir quelque données vient d'être sélectionnées de la base de données.Un exemple du code PHP qui permet de générer un document XML peut être trouvé à fonctions DOM à l'aide de PHP 5 pour créer des fichiers XML de données SQL. Il est possible donc de créer des applications web complètes où les scripts PHP ne contiennent pas les balises HTML du tout. Tout ce qu'ils font c'est créer des fichiers XML à partir de requêtes de base de données, puis utilisation des transformations XSL pour générer les documents HTML.

Cette méthode divise complètement la couche de présentation (c'est-à-dire la génération de documents HTML) de la couche métier (l'application de règles d'entreprise en utilisant un langage comme PHP) et que chaque une de ces couches peut être modifiée sans affecter l'autre.

Tout le code décrit dans le présent document est contenu dans le téléchargeable exemple d'application.

Conditions préalables

Vous devez avoir une version de PHP qui a été compilé avec XML et XSL .

On suppose également que vous avez quelques connaissances de XML et XSL.

Un exemple de fichier XML

Voici un exemple de document XML. Il peut soit être créé par un processus externe, ou il peut être créé par un script PHP tels que  la procédure décrite dans le chapitre les fonctions DOM à l'aide de PHP 5 pour créer des fichiers XML de données SQL.

  Sélectionner le code

<?xml version="1.0"?>
<exemple.personne>
  <personne>
    <personne_id>PA</personne_id>
    <nom>Pamela</nom>
    <prenom>Anderson</prenom>
    <initiales>pa</initiales>
    <symbole>Lion</symbole>
  </personne>
  <personne>
    <personne_id>KB</personne_id>
    <nom>Tomm</nom>
    <prenom>Basinger</prenom>
    <initiales>kb</initiales>
    <symbole>Sagittaire</symbole>
  </personne>
  <personne>
    .....
  </personne>
  <actionbar>
    <button id="personne_search.php">CHERCHER</button>
    <button id="reset">ANNULER</button>
    <button id="finish">TERMINER</button>
  </actionbar>
</exemple.personne>

 

Un fichier XML contient une collection de nœuds qui doit avoir une balise d'ouverture (<nœud>) et une balise de fermeture correspondante (</nœud>). Un nœud peut contenir du texte ou un nombre quelconque de nœuds enfants. La balise d'ouverture d'un nœud peut également contenir un nombre quelconque d'attributs au format attribut="value".

Un exemple de fichier XSL

Voici un exemple de document de feuille de style XSL. Ces fichiers existent en dehors de PHP et peuvent même être sous le contrôle d'une équipe distincte de développeurs.

  Sélectionner le code

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method='html'/>
<!-- Les param valeurs peuvent être modifiées au cours de la
Transformation XSL -->
<xsl:param name="title">Liste des PERSONNE</xsl:param>
<xsl:param name="script">personne_list.php</xsl:param>
<xsl:param name="numrows">0</xsl:param>
<xsl:param name="pageCourante">1</xsl:param>
<xsl:param name="dernierePage">1</xsl:param>
<xsl:param name="script_time">0.3714</xsl:param>

<!-- include des modèles communs -->
<xsl:include href="std.pagination.xsl"/>
<xsl:include href="std.actionbar.xsl"/>

<xsl:template match="/">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title><xsl:value-of select="$title"/></title>
    <style type="text/css">
      <![CDATA[
      <!--
        caption { font-weight: bold; }
        th { background: #cceeff; }
        tr.odd { background: #eeeeee; }
        tr.even { background: #dddddd; }
        .center { text-align: center; }
      -->
      ]]>
    </style>
</head>
<body>
  <form method="post" action="{$script}">
  <div class="center">
  <table border="0">
    <caption><xsl:value-of select="$title"/></caption>
    <thead>
      <tr>
        <th>Personne ID</th>
        <th>Nom</th>
        <th>Prénom</th>
        <th>Symbole</th>
      </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="//personne" />
    </tbody>
  </table>
        
  <!-- insérer des liens de navigation de la page -->
  <xsl:call-template name="pagination" />
  <!-- créer des boutons d'action standard -->
  <xsl:call-template name="actionbar"/>
  </div>
  </form>
</body>
</html>
</xsl:template>
<xsl:template match="personne">
  <tr>
    <xsl:attribute name="class">
      <xsl:choose>
        <xsl:when test="position()mod 2">odd</xsl:when>
        <xsl:otherwise>even</xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
    <td><xsl:value-of select="personne_id"/></td>
    <td><xsl:value-of select="first_name"/></td>
    <td><xsl:value-of select="last_name"/></td>
    <td><xsl:value-of select="star_sign"/></td>
  </tr>
</xsl:template>
</xsl:stylesheet>

 

Contenu du fichier XSL

Comme vous pouvez voir le fichier XSL contient un mélange de balises HTML standard et une série d'autres balises qui ont la <xsl: préfixe. 

Ceci est similaire à un script PHP qui peut contenir un mélange de balises HTML et des instructions PHP. 

Tout ce qui se trouve dans une balise XSL est en quelque sorte traité par le moteur XSLT, alors que tout le reste sera affiché tel quel est.

Notez que cet exemple a ses définitions CSS définies en interne. Dans un environnement de production adéquate, j'attendrais ce qui doit se tenir dans un fichier externe.

Voici une explication des diverses balises XSL :

 

< xsl: stylesheet >

Tout dans cette balise est une feuille de style. Notez que la première déclaration de stylesheet identifie l’espace de nom officiel de la recommandation W3C XSL et le numéro de la version.

< xsl: output / >

Il contrôle le format de la sortie de la feuille de style. La valeur par défaut est « html », il y a d'autres options comme « xml » ou « text ». Notez que l'extension Sablotron permet une méthode de « xhtml » qui fait en sorte que la sortie est conforme au langage XHTML plutôt que la norme HTML.

< param >

Ceci identifie un paramètre qui peut être référencé par son nom à partir de n'importe où dans la feuille de style (mais avec un préfixe « $»). Une valeur par défaut peut être déclarée dans la feuille de style, même si une valeur différente peut-être fournie pendant le processus de transformation.

< xsl : include / >

Ceci est similaire à la fonction include de PHP. Il permet de spécifier des feuilles de style communes qui peuvent être incluses quand c’est nécessaire. Notez que vous devrez utiliser la commande xsl_set_base() dans votre script PHP afin de définir le répertoire de base qui contient les fichiers include.

< ![CDATA [...]]>

Identifie un élément de texte qui est ignoré par l'analyseur XML. Sans cela le ' <' et ' >' provoquerait des erreurs car l'analyseur les traiterait comme s'ils faisaient partie de début et de fin des balises.

< xsl: template match = "/" >

Cela définit le début d'un modèle. Le match="/" attribut associe  le modèle à la racine  du document XML source.

< xsl : apply-templates  / > ;

Cela définit un ensemble de nœuds à traiter. Le select="//personne" attribut identifie les nœuds avec le nom « personne ». Le ' / /' est utilisé pour signifier « enfant du nœud racine ». Cela va chercher un modèle qui correspond à cette règle, dans ce cas <xsl:template match="personne" >.

< xsl: call-template / >

Ceci est utilisé pour appeler un modèle nommé, identifié par l'attribut name. Ceci est équivalent à l'appel d'une fonction au sein de PHP. Cela va chercher un modèle qui correspond à cette règle, dans ce cas <xsl:template name="..." >

< xsl: value-of / >

Cela affiche la valeur de chaîne de l'expression. L'expression peut être une des opérations suivantes :

Si elle a un préfixe « $» il identifie le <xsl:param> portant ce nom.

Sans ce préfixe, il identifie un nœud dans le chemin d'accès actuel du document XML.

Noter que, dans certains cas, cette balise peut être réduite à une expression entre accolades, comme {$script}. Ceci est similaire à l'utilisation d'accolades dans PHP.

position()

Cela équivaut à la position du noeud testé parmi ses frères et sœurs du même nom (c'est-à-dire son numéro de ligne). Notez que ce nombre commence à partir de 1, pas 0 comme dans PHP.

mod

On obtient le module de l'expression spécifiée. Par exemple, position()mod 2 nous dit que le numéro de ligne du nœud actuel soit impair.

< xsl:attribute >

Insère un attribut dans la balise HTML.

< xsl: choose > 
< template > 
< xsl:otherwise >

Ce qui équivaut à IF .... ELSEIF .... ELSE

Fichiers XSL Include

Il est possible de stocker des modèles communs dans des fichiers séparés et de les intégrer à votre feuille de style au moment de l'exécution par le biais de la commande <xsl:include> .

Voici les listes et les explications sur les fichiers include utilisés dans cet exemple.

 

STD.pagination.Xsl

  Sélectionner le code

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template name="pagination">
  <table border="0" class="pagination">
    <tr class="pagination">
      <xsl:choose>
        <xsl:when test="$pageCourante&lt;=1">
          <!-- Nous sommes à la page 1, donc il n'y a aucune navigation vers l'arrière -->
          <td class="pagination">FIRST</td>
          <td class="pagination">PREV</td>
        </xsl:when>
        <xsl:otherwise>
          <!-- insérer des liens pour page première/précédente -->
          <td class="pagination"><a href="{$script}?page=1"><b>FIRST</b></a></td>
          <td class="pagination"><a href="{$script}?page={$pageCourante-1}"><b>PREV</b></a></td>
        </xsl:otherwise>
      </xsl:choose>
      <!-- insert "page x of y" -->
      <td class="pagination">
        <xsl:text>Page </xsl:text>
        <xsl:value-of select="$pageCourante"/>
        <xsl:text> of </xsl:text>
        <xsl:value-of select="$dernierePage"/>
      </td>
      <xsl:choose>
        <xsl:when test="$pageCourante=$dernierePage">
          <!-- Nous sommes à la dernière page, alors il n'y a aucune navigation vers l'avant -->
          <td class="pagination">NEXT</td>
          <td class="pagination">LAST</td>
        </xsl:when>
        <xsl:otherwise>
          <!-- insérer des liens pour les dernières et prochaines page -->
          <td class="pagination"><a href="{$script}?page={$pageCourante+1}"><b>NEXT</b></a></td>
          <td class="pagination"><a href="{$script}?page={$dernierePage}"><b>LAST</b></a></td>
        </xsl:otherwise>
      </xsl:choose>
    </tr>
  </table>
</xsl:template>
</xsl:stylesheet>

 

$pageCourante, $dernierePage et $script sont des paramètres définis avec la balise <xsl:param> , et qui peuvent avoir les valeurs fournies au moment de l'exécution pendant le processus de transformation XSL. L'accès à ces valeurs permet à ce modèle à la sortie  ce qui suit :

Si nous sommes actuellement au-delà de la première page, des hyperliens seront générés pour revenir à la première page et  à la page précédent. 

Si nous sommes actuellement sur la première page, il n'y n'aura aucun lien hypertexte, juste le texte brut. Nous pouvons montrer à l'utilisateur le numéro de page actuel et le nombre total de pages.

Si nous sommes actuellement avant la dernière page,  des liens hypertexte seront générés pour aller vers l'avant aux prochaine et dernière pages. 

Si nous sommes actuellement à la dernière page, il n'y n'aura aucun lien hypertexte, juste le texte brut.

 

STD.ActionBar.Xsl

  Sélectionner le code

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="actionbar">
  <table border="0" class="actionbar">
    <tr class="actionbar">
      <xsl:for-each select="//actionbar/*">
        <!-- créer un bouton pour chaque élément dans actionbar -->
        <td class="actionbar">
           <input type="submit" name="{@id}" value="{node()}" />
        </td>
      </xsl:for-each>
    </tr>
  </table>
  <p class="script_time"> Page chargée <xsl:value-of
select="$script_time"/> seconds</p>
</xsl:template>

</xsl:stylesheet>

 

< xsl : for-each >

Ceci est similaire à la fonction foreach de PHP. La directive "//actionbar/*" sélectionne tous les enfants du nœud actionbar disponibles.

(@id)

Cela va afficher le contenu de l'attribut avec le nom « id ».

{node()}

Cela va afficher la valeur du nœud actuel.

$script_time

C'est l'un des paramètres qui ont été spécifiés pendant le processus de transformation.

 

Cette méthode signifie que les boutons sur la barre d'action ne sont pas durs codé dans le script XSL, mais ils sont spécifiés dans les données XML. Ainsi, le processus qui génère les données XML peut varier les boutons d'action selon sa propre logique interne.

 

Effectuer la Transformation XSL

Vous trouverez qu'il existe de nombreuses options disponibles lorsque vous venez d'effectuer la transformation XSL. Voici quelques-unes de ces options avec une explication de leur utilisation.

 

Création d'une ressource XSLT processor

Pour cela, une seule instruction simple :

 
  $xp = new XsltProcessor();
 

Identifier et charger la feuille de style XSL

 

On obtient la feuille de style XSL à partir d'un fichier externe et le charger dans la ressource XSLT. Il se chargera également dans des modèles externes spécifiés avec le <xsl:include>commande.

  // Créez un document DOM et charger la feuille de style XSL
  $xsl = new DomDocument;
  $xsl->load('something.xsl');
  // importer la feuille de style XSL dans le processus XSLT
  $xp->importStylesheet($xsl);
 

Identification du document XML

 

On obtient les données XML d'un fichier externe et on le charge dans une instance de document séparé.

  // Créer un document DOM et charger les données XML
  $xml_doc = new DomDocument;
  $xml_doc->load('MonFichierXML.xml');

Alternativement, le document XML peut être créé dynamiquement à l'aide de la procédure décrite dans les fonctions DOM à l'aide de PHP 5 pour créer des fichiers XML de données SQL.

 

Définition des paramètres optionnels

 

Utilisez cette méthode pour charger les paramètres optionnels que vous souhaitez passer au processus de transformation XSL. Notez qu'avec la version 5.0.0 de PHP, vous devez charger les paramètres un à la fois :

 
  $xp->setParameter($namespace, 'id1', 'value1');
  $xp->setParameter($namespace, 'id2', 'value2');

Avec PHP version 5.1.0 vous serez capable de créer un tableau de paramètres et de le charger:

 
  $params['id1'] = 'value1';
  $params['id2'] = 'value2';
  ....
  $xp->setParameter($namespace, $params);
 

Invoquant le processus XSLT et afficher le résultat

Ceci implique l'utilisation de la méthode de transformation de la ressource XSLT créée et lier avec un document XML spécifié :

 
  // Transformer du XML en HTML à l'aide du fichier XSL
  if ($html = $xp->transformToXML($xml_doc)) {
      echo $html;
  } else {
      trigger_error('La transformation XSL a échoée.', E_USER_ERROR);
  }
 

exemple de sortie

 

Si vous effectuez la transformation XSL en utilisant les exemples de fichiers XML et XSL fournies dans cet article les résultats devraient ressembler à ce qui suit :

 

transformation XSL  

Si l'apparence n'est pas tout à fait à votre goût, vous pouvez la modifier, non pas en modifiant tout le code PHP, mais en modifiant les définitions de feuille de style contenues dans soit votre.Fichier CSS ou votre.Fichier XSL.

Tout le code décrit dans le présent document est contenu dans le téléchargeable exemple d'application.

Par carabde 30 mars 2015