Sommaire déroulant

Contenu du snippet

Sommaire déroulant (xml+xslt+css+javascript+php5)

J'ai été surpris de ne pas trouver ce type de code, mais peut-être n'ai-je pas cherché au bon endroit?
La question se pose en effet de la présence de ce code ici, vu qu'il ne comporte que 3 lignes de php "véritable"; cependant, à force de lire les posts, j'ai compris que le traitement des fichiers au format xml constituait une préoccupation majeure de la plupart d'entre vous.
A vous de juger.
Quelques explications :
L'idée même de sommaire déroulant suppose la différenciation des chapitres en 2 catégories :
- les chapitres de type "branche" (assimilables aux "dossiers" d'une arborescence), d'expression xpath :
//chapitre[chapitre]
et qui contiennent d'autres chapitres.
- les chapitres de type "feuille" (assimilables aux "fichiers" d'une arborescence), d'expression xpath :
//chapitre[not(chapitre)]
et qui contiennent le texte "utile" du document.
- Question : et si un chapitre de type "branche", en plus de contenir des chapitres, contient aussi du texte?
- Réponse : son texte sera ignoré.

Source / Exemple :


<?php
header('Content-type: text/html; charset=iso-8859-1');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
?>

<html>

<!-- 
 - Date de création : 16/08/2007
 - Objet : sommaire déroulant (xml+xslt+css+javascript+php5)
 - Auteur : opossum_farceur
-->

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content=0> 
<title></title>

<style type="text/css">
   body {background-color:white; font-family:Arial;}

   TABLE.table1 {width:100%; border:1px solid black;}
   TH.th1 {background-color:#EEEEEE; border:1px solid black; padding:20px; font-size:32px;}
   TD.td1 {background-color:#EEEEEE; border:1px solid black; padding:20px; font-size:14px; text-align:justify;}

   TABLE.table2 {width:100%; border-style:none;}
   TD.left {border-style:none; padding:0px; font-size:18px; color:blue;}
   TD.right {border-style:none; padding:0px; text-align:right;}

   SMALL {font-size:5px;}  /* pour gérer les espaces entre les "icônes" */

   UL {margin-left:20px; padding-left:0px;}
   UL.root {margin-left:0px;}
   UL.off {display:none;}
   UL.on {}
   LI.nomarker {list-style-type:none;}

   A {color:blue;}
   A.summary {text-decoration:none; font-size:18px;}
   A.symbol {font-size:22px;}
   A:hover {color:red;}
                           /* largeur du span pas traitée avec FF, pb aussi si le lien est souligné */
   SPAN.sign {font-family:Courier New; font-size:20px; font-weight:bold; color:magenta; padding-right:10px;}
   SPAN.number {color:black; padding-right:10px;}
</style>

<script language="Javascript">

/////////////////////////////////////////////////////////////////////////////////////////////////////////

function change(tag,id)
{
   var ul=document.getElementById(id),s=tag.innerHTML;

   if (ul.className=='off') {
      ul.className='on';
      tag.innerHTML=s.replace(/[+]/,'-');       // seul le premier caractère trouvé est remplacé
   }
   else {
      ul.className='off';
      tag.innerHTML=s.replace(/[-]/,'+');
   }
   tag.style.color='purple';
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

</script>
</head>

<body>
<?php

$xml=<<<XML
<document titre="--- &#160; Ma petite DEMO &#160; ---">
   <chapitre titre="Chapitre un">
      <chapitre titre="Chapitre un/un">
         <P style="font-size:60px; color:teal;">
            Bonjour,<BR/>ceci est le texte<BR/>du Chapitre un/un<BR/><BR/>
         </P>
      </chapitre>
      <chapitre titre="Chapitre un/deux">
         <P style="font-size:60px; color:silver;">
            Bonjour,<BR/>ceci est le texte<BR/>du Chapitre un/deux<BR/><BR/>
         </P>
      </chapitre>
      <chapitre titre="Chapitre un/trois">
         <chapitre titre="Chapitre un/trois/un">
            <P style="font-size:60px; color:olive;">
               Bonjour,<BR/>ceci est le texte<BR/>du Chapitre un/trois/un<BR/><BR/>
            </P>
         </chapitre>
      </chapitre>
   </chapitre>
   <chapitre titre="Chapitre deux">
      <chapitre titre="Chapitre deux/un">
         <P style="font-size:60px; color:navy;">
            Bonjour,<BR/>ceci est le texte<BR/>du Chapitre deux/un<BR/><BR/>
         </P>
      </chapitre>
      <chapitre titre="Chapitre deux/deux">
         <P style="font-size:60px; color:maroon;">
            Bonjour,<BR/>ceci est le texte<BR/>du Chapitre deux/deux<BR/><BR/>
         </P>
      </chapitre>
   </chapitre>
</document> 
XML;

$xsl='
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="ISO-8859-1"/>

<xsl:template match="document">
   <TABLE class="table1">
      <TR><TH class="th1">                               <!-- titre du document -->
         <xsl:value-of select="@titre"/>
      </TH></TR>

      <TR><TD class="td1">                               <!-- traitement du sommaire : parcours récursif -->
         <UL class="root">
            <xsl:apply-templates select="chapitre"/>
         </UL>
      </TD></TR>

      <xsl:for-each select="//chapitre[not(chapitre)]">  <!-- traitement du "contenu" : parcours itératif -->
         <xsl:variable name="pos" select="position()"/>
         <TR><TD class="td1">
            <TABLE class="table2"><TR>
               <TD class="left" id="{$pos}">             <!-- à gauche, le titre du chapitre -->
                  <SPAN class="number"><xsl:number level="multiple"/></SPAN>
                  <xsl:value-of select="@titre"/>
               </TD>
               <TD class="right"><FONT face="Webdings">  <!-- à droite, le système de "navigation" -->
                  <A class="symbol" href="#top" title="top">9</A>
                  <xsl:if test="$pos > 1">
                     <SMALL>&#160;</SMALL><A class="symbol" href="#{$pos - 1}" title="précédant">3</A>
                  </xsl:if> 
                  <xsl:if test="$pos < last()">       <!-- espaces autour du "+" nécessaires -->
                     <SMALL>&#160;</SMALL><A class="symbol" href="#{$pos + 1}" title="suivant">4</A>
                  </xsl:if> 
               </FONT></TD>
            </TR></TABLE>

            <xsl:copy-of select="."/>                    <!-- copie du "contenu" sans traitement particulier -->
         </TD></TR>
      </xsl:for-each>

   </TABLE>
</xsl:template>

<xsl:template match="chapitre">
   <xsl:choose>
      <xsl:when test="./chapitre">                       <!-- c`est donc une "branche"! -->
         <xsl:variable name="idvalue" select="generate-id()"/>
         <LI class="nomarker">
            <A class="summary" href="#" onClick="change(this,\'{$idvalue}\');">
               <SPAN class="sign">+</SPAN>
               <SPAN class="number"><xsl:number level="multiple"/></SPAN>
               <U><xsl:value-of select="@titre"/></U>
            </A>
            <UL id="{$idvalue}" class="off">             <!-- identifiant fourni par "generate-id()" -->
                <xsl:apply-templates select="chapitre"/>
            </UL>
         </LI>
      </xsl:when>
      <xsl:otherwise>                                    <!-- c`est donc une "feuille"! -->
         <LI class="nomarker">
            <A class="summary" href="#{count(preceding::chapitre[not(chapitre)]) + 1}" onClick="this.style.color=\'purple\';">
               <SPAN class="sign">&#160;</SPAN>
               <SPAN class="number"><xsl:number level="multiple"/></SPAN>
               <U><xsl:value-of select="@titre"/></U>
            </A>
         </LI>
      </xsl:otherwise> 
   </xsl:choose>
</xsl:template>

</xsl:stylesheet>
';

$proc=new XSLTProcessor;
$proc->importStyleSheet(DOMDocument::loadXML(utf8_encode($xsl)));
echo $proc->transformToXML(DOMDocument::loadXML(utf8_encode($xml)));
?>
</body></html>

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.