probleme de mise en forme xml

Petit nouveau ! | 3 Messages

30 mars 2009, 12:48

bonjour,

je souhaite parcourir avec php un ensemble de répertoires et lister l'ensemble des fichiers contenu
avec l'arborescence suivante

Code : Tout sélectionner

<?xml version='1.0' encoding='UTF-8' ?> <dossiers> <année nom = "2009" > <mois nom="janvier"> <image nom="le_nom.jpg"/> <image nom="autre_nom.jpg"/> </mois> <mois nom="fevrier"> <image nom="le_nom.jpg"/> <image nom="autre_nom.jpg"/> </mois> </année> </dossiers>
mes répertoires sont organisés de la manière suivante:

Code : Tout sélectionner

images/ --------/2009/ ---------------/janvier/ ------------------------/image.jpg ---------------/fevrier/ ------------------------/image.jpg
j'ai essayé de parcourir les dossiers avec le code ci-dessous, mais je n'arrive pas à le mettre en forme.



<?php

function ScanDirectory($Directory){

  $MyDirectory = opendir($Directory) or die('Erreur');

$file= fopen("galeriePhoto.xml", "w");
$_xml ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";

	while($Entry = @readdir($MyDirectory)) {
		if(is_dir($Directory.'/'.$Entry)&& $Entry != '.' && $Entry != '..') {			

			echo  $Directory.'/'.$Entry ;
			ScanDirectory($Directory.'/'.$Entry);
                        
		}	
		else {

			echo $Entry;

                }
	}

  closedir($MyDirectory);
fwrite($file, $_xml); 
fclose($file);
}
ScanDirectory('.');
?>

  
si vous avez une idée pour un ptit coup de pouce je vous remercie d'avance !

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

30 mars 2009, 14:26

Bonjour,

A mon humble avis, le code est bon en ce qui concerne le parcourt du dossier mais il n'est pas bon au niveau de l'écriture du fichier XML.

En effet, la fonction ScanDirectory réalise un parcourt récursif du dossier donné comme paramètre pour ainsi parcourir les sous-dossiers s'y trouvant. Mais on remarque, que tu crée ton fichier XML (oouverture en mode "w") au début de la fonction, ce qui engendre la recréation à vide du fichier XML à chaque niveau de récursivité de la fonction. En clair, quand un sous-dossier est rencontré par le scan, la fonction est ré-appelée et du coup le fichier XML est ré-ouvert en mode "w".

Ce n'est pas bon. Il faut répartir les niveaux des tâches de création et écriture du contenu du fichier XML selon les niveaux de récursivité de la tâche du parcourt des dossiers.

Et pour cela il faut aussi répartir l'écriture des structures XML selon les niveaux du parcourt des dossiers.

L'algorithme préconisé est le suivant:
--------------------------------------

1. Ouvrir le fichier XML en mode écriture (1 fois)
2. Inscrire la structure XML de l'entête : (S1)
----
3. Parcourir le dossier
4. Pour le dossier en cours, Inscrire la structure XML : (S2) si c'est un dossier "année" ou (S3) si "mois"
5. Si un fichier est trouvé, alors, l'inscrire dans la structure XML : (S4).
6. Si un sous-dossier est rencontré, alors, inscrire la structure XML : (S5) si le dossier précédent est un "mois" ou (S6) si "année"
en suite, il faut refaire l'algortihme (par récursivité) à partir de la tâche 3.
----
7. Si la tâche 6 n'a pas trouvé de sous-dossiers, la récursivité est terminée. Il faut Inscrire alors la structure XML de terminaison : (S7)
8. Fermer le fichier XML et fin du programme.
---------------------------------------------

Le codes de structures : S1, S2, ... utilisés dans le programme correspondent au découpage du fichier XML selon la spécifité de chaque description.
Voici le découpage que je préconise:

La stucture de l'entête (que je nomme: S1) (figurera 1 fois au début)
------------------------------------------
<?xml version='1.0' encoding='UTF-8' ?>
<dossiers>

La stucture de début d'un dossier de type ANNEE (que je nomme: S2) (figurera à chaque fois un sous-dossier "année" est rencontré)
------------------------------------------------------------------
<année nom = "...." >

La stucture de début d'un dossier de type MOIS (que je nomme: S3) (figurera à chaque fois un sous-dossier "mois" est rencontré)
-----------------------------------------------------------------
<mois nom="....">

La stucture descriptive d'un fichier (image) (que je nomme: S4) (figurera autant de fois qu'il y a de fichiers dans le dossier "mois" traité)
---------------------------------------------------------------
<image nom="......."/>

La stucture de fin d'un dossier de type MOIS (que je nomme: S5) (figurera à la fin des écritures des fichiers d'un dossier "mois")
---------------------------------------------------------------
</mois>

La stucture de fin d'un dossier de type ANNEE (que je nomme: S6) (figurera à la fin des écritures des sous-dossiers de type "mois")
----------------------------------------------------------------
</année>

La stucture de fin du fichier XML (que je nomme: S7) (figurera 1 fois à la fin)
---------------------------------
</dossiers>
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Petit nouveau ! | 3 Messages

30 mars 2009, 21:01

et bien merci je vais essayer cela !

sinon je vais me pencher sur le DOM
ça m'as l'air interessant !!

merci encore pour la rapidité de réponse :wink:

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

31 mars 2009, 09:51

Voici un essai, qui colle avec l'algorithme que j'ai présenté:
<?php  
//////////////////////////////////////////////////////////////////////////////////////////////////////// 
//FONCTION DirectoryToXML QUI PARCOURT LES DOSSIERS DES PHOTOS ET ECRIT XML 
// @params :  
//                 $Directory : Dossier à parcourir (en entrée) 
//                 $_xml       : variable globale partagée avec le programme principal 
//                                    contenant le tableau XML à enrichir 
// @Retour : rien 
//////////////////////////////////////////////////////////////////////////////////////////////////////// 
function DirectoryToXML($Directory){ 
    global $_xml; //variable globale partagée 
     
    // Parcourir le dossier donné en paramètre  
    $MyDirectory = opendir($Directory) or die('Erreur');  
        while($Entry = @readdir($MyDirectory)) {  
            if($Entry != '.' && $Entry != '..') {               
                 
                if (is_dir($Directory.'/'.$Entry)){ 
                    echo "<h5>Inscription XML: $Entry</h5><ul>"; 
                    //Sous-dossier détécté, inscrire 'S2' si année, sinon 'S3' si mois, sinon l'entrée est enregistrée comme nouvelle balise 
                    if (estAnnee($Entry)) $_xml['DOC'][] = sprintf($_xml['S2'], $Entry); // année 
                    else if (estMois($Entry)) $_xml['DOC'][] = sprintf($_xml['S3'], $Entry); // mois 
                    else $_xml['DOC'][] = sprintf($_xml['DOSSIER_INCONNU'], $Entry); // ni mois ni année 
                    //ré-appel de la fonction en récurisivité à fin de refaire le même  
                    //traitement sur le nouveau dossier rencontré à ce niveau 
                    DirectoryToXML($Directory.'/'.$Entry); 
                    //Fin de traitement du sous-dossier, inscrire les fins de balises 'S5' si mois sinon 'S6', sinon fin de nouvelle balise 
                    if (estMois($Entry)) $_xml['DOC'][] = sprintf($_xml['S5'], $Entry); // mois 
                    else if (estAnnee($Entry)) $_xml['DOC'][] = sprintf($_xml['S6'], $Entry); // année 
                    else $_xml['DOC'][] = sprintf($_xml['/DOSSIER_INCONNU'], $Entry); // ni mois ni année 
                    echo "</ul>"; 
                }      
                else {  
                    //Fichier détécté: l'inscrire dans XML ('S4') 
                     $_xml['DOC'][] = sprintf($_xml['S4'], $Entry); 
                    echo "<li>Inscription XML: $Entry</li>"; 
                } 
            }  
        } 
    //FIN. 
    closedir($MyDirectory); 
                return $_xml['DOC'];    
} 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//FONCTIONS POUR DETECTER LES MOIS ET LES ANNEES 
// 
//  La fonction estMois(texte) : reçoit un nom de mois, le valide et renvoit vrai si c'est un mois  
//  connu dans la liste des mois gérée par le programme. 
//  La fonction estAnnée(nombre) : reçoit une année, le valide et renvoit vrai si c'est une année  
//  connue dans la liste des années gérée par le programme. 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

//Listes des mois et années gérées par le programme 
$mois = array('janvier','fevrier','mars','avril','mai','juin', 
    'juillet','aout','septembre','octobre','novembre','decembre'); 
$années = array(2008,2009); 

function estAnnee($nombre){ 
    global $années; 
    if (in_array(trim($nombre), $années)) return true; else return false; 
} 
function estMois($texte){ 
    global $mois; 
    if (in_array(strtolower(trim($texte)), $mois)) return true; else return false; 
} 

//////////////////////////////////////////////////////////////////////////////////////////////////////// 
// 
//             PROGRAMME  PRINCIPAL 
// 
///////////////////////////////////////////////////////////////////////////////////////////////////////// 

//DECOUPAGE DES STRUCTURES XML SOUS FORME DE MASQUES (%s=texte à remplacer, \t=tabulation, \r\n=retour à la ligne) 
$_xml['S0'] = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
. "<?xml-stylesheet type=\"text/xsl\" href=\"galeriePhoto.xsl\"?>\r\n"; // associer xml à une présentation XSLT
$_xml['S1'] = "<dossiers>\r\n"; 
$_xml['S2'] = "\t<annee nom=\"%s\" >\r\n"; 
$_xml['S3'] = "\t\t<mois nom=\"%s\" >\r\n"; 
$_xml['S4'] = "\t\t\t<image nom=\"%s\"/>\r\n"; 
$_xml['S5'] = "\t\t</mois>\r\n"; 
$_xml['S6'] = "\t</annee>\r\n"; 
$_xml['S7'] = "</dossiers>\r\n"; 
$_xml['DOSSIER_INCONNU'] = "\t<%s>\r\n"; //format réservé pour créer une balise pour  
$_xml['/DOSSIER_INCONNU'] = "\t</%s>\r\n"; // les dossiers qui ne sont ni mois ni années et qui peuvent exister dans le dossier parcouru 

//REDACTION XML ET LANCEMENT DU SCAN: 3 2 1 0 GO 
$_xml['DOC'][] = $_xml['S0']; 
$_xml['DOC'][] = $_xml['S1']; 
DirectoryToXML('photos/'); //Génére les structure XML: 'S2','S3','S4','S5' et 'S6' 
$_xml['DOC'][] = $_xml['S7']; 

//ECRITURE FICHIER XML 
file_put_contents("galeriePhoto.xml", implode("", $_xml['DOC']));
echo "<a href=\"galeriePhoto.xml\">Afficher le fichier XML de la galerie de Photos</a>"; //afficher le fichier XML 
?>  
L'arborescence de dossiers parcourue est la même que tu as présenté:

PHOTOS (dossier principal contenant les photos par année et par mois)
|
|_________ 2008
|_________|
|_________|_____ Janvier
|_________|_____|
|_________|_____|______ Image 1.xxx
|_________|_____|______ ...
|_________|_____|______ Image N.xxx
|_________|_____|
|_________|_____ Février
|_________|_____|
|_________|_____|______ Image 1.xxx
|_________|_____|______ ...
|_________|_____|______ Image N.xxx
| .....
| .....

[EDIT]
J'ai associé une présentation XSLT au fichier XML, pour afficher ses données sous forme d'une galerie d'images sur une page HTML. Voici, le fichier XSL associé:

Modèle XSLT: galeriePhoto.xsl

Code : Tout sélectionner

<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="dossiers"> <html> <body> <h2>Galerie Photos</h2> <table border="1"> <xsl:for-each select="annee"> <tr bgcolor="#9acd32" ><th colspan="2"><xsl:value-of select="@nom"/></th></tr> <xsl:variable name="chemin1"> <xsl:value-of select="'photos/'"/> <xsl:value-of select="@nom"/> <xsl:text>/</xsl:text> </xsl:variable> <xsl:for-each select="mois"> <tr bgcolor="#9acd64"><th colspan="2"><xsl:value-of select="@nom"/></th></tr> <xsl:variable name="chemin2"> <xsl:value-of select="$chemin1"/> <xsl:value-of select="@nom"/> <xsl:text>/</xsl:text> </xsl:variable> <xsl:for-each select="image"> <tr> <td> <xsl:element name="img"> <xsl:attribute name="src"> <xsl:value-of select="$chemin2"/><xsl:value-of select="@nom"/> </xsl:attribute> <xsl:attribute name="width">150px</xsl:attribute> <xsl:attribute name="height">100px</xsl:attribute> </xsl:element> </td> </tr> </xsl:for-each> </xsl:for-each> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
J'ai édité le code du programme pour faire cette association par la déclaration XML suivante:
<?xml-stylesheet type="text/xsl" href="galeriePhoto.xsl"?>
Alors quand le programme génére le fichier XML, il affiche un lien hypertexte qui propose d'afficher le fichier XML.
Une fois démarré, le fichier XML appelle le fichier XSL pour afficher ses données selon la présentation HTML du modèle XSL.
Modifié en dernier par sadeq le 01 avr. 2009, 13:40, modifié 6 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Petit nouveau ! | 3 Messages

31 mars 2009, 11:40

je te remercie pour ton aide !
un sujet de plus résolu !