Algorithme recursif

Résolu
Perecastorr Messages postés 39 Date d'inscription lundi 10 novembre 2008 Statut Membre Dernière intervention 7 septembre 2010 - 11 mars 2010 à 12:46
Perecastorr Messages postés 39 Date d'inscription lundi 10 novembre 2008 Statut Membre Dernière intervention 7 septembre 2010 - 11 mars 2010 à 15:27
Bonjour,

Mon problème étant très spécifique et assez compliqué je vais essayé d'être le plus clair possible.
J'ai un script PHP qui prend en parametre (via POST) un XML contenant une description d'une arborescence de fichier, de dossier dans des groupes de travails.

Dans une base de données, j'ai une corespondance de ces groupes de travails, dossier et fichiers stockés dans des tables. L'arborescence est elle aussi présente dans la base de données grâces aux clés etrangere.

Le but est de renvoyer un XML contenant la même arborescence mais avec champs "valeur1", "valeur2" des fichiers de la base de données, mais aussi d'ajouter dans le XML de retour, les dossiers (mais pas les fichiers) qui ne sont pas dans l'arborescence en parametre.

Je vais essayer de récapituler :
XML Parametre d'entree
<gdt id="gdt1">
<dossier id="dossier1">
<fichier id="fichier1" />
</dossier>
</gdt>

Base de données (schématisation XML)

<gdt id="gdt1">
<dossier id= "dossier1">
<fichier id="fichier1" valeur1="..." valeur2="..." />
<fichier id="fichier2" valeur1="..." valeur2="..." />
</dossier>
<dossier id ="dossier2">
<fichier id= "fichier3" valeur1="..." valeur2="..." />
<dossier id="dossier3">
</dossier>
</dossier>
</gdt>

BUT RECHERCHER : XML afficher (retour)
<gdt id="gdt1">
<dossier id="dossier1">
<fichier id="fichier1" valeur1="..." valeur2="..." />
</dossier>
<dossier id = "dossier2">
<dossier id="dossier3">
</dossier>
</dossier>
</gdt>



J'ai déja un code PHP qui permet d'obtenir cela :
<gdt id="gdt1">
<dossier id="dossier1">
<fichier id="fichier1" valeur1="..." valeur2="..." />
</dossier>
</gdt>


Dont le code est le suivant :
<?php
$db = new PDO('mysql:host=localhost;dbname=LeapFrog', 'root', '');
$xmlData = simplexml_load_string($_POST["xmlData"]);
$resultat = "<root>";

foreach($xmlData->children() as $idGdT => $GdT) 
{
$BddGdt = checkEnregistrement("gdt", $GdT["id"]);
if ($BddGdt != null)
{
$resultat .= '<gdt id="'.$BddGdt["id_gdt"].'" nom="'.$BddGdt["nom_gdt"].'" moderateur ="'.$BddGdt["id_user"].'" >';
$resultat = parcourrirDossier($GdT, "gdt", $idGdT, $resultat);
$resultat .= "</gdt>";	
}
}
$resultat .= "</root>";
echo $resultat;

function parcourrirDossier($racine, $typeRacine, $idRacine, $resultat)
{
foreach ($racine->dossier as $idDossier=> $dossier)
{
$BddDossier = checkEnregistrement("dossier", $dossier["id"]);
if ($BddDossier != null)
{
$resultat .= '<dossier id="'.$BddDossier["id_dossier"].'" nom="'.$BddDossier["nom_dossier"].'">';
$resultat = parcourrirDossier($dossier, "dossier", $idRacine, $resultat);
$resultat .= "</dossier>";
}

}
foreach ($racine->fichier as $idfichier => $fichier)
{

$BddFichier = checkEnregistrement("fichier", $fichier["id"]);
if($BddFichier != null)
{
$resultat .= '<fichier ';
$resultat .= 'id="'.$BddFichier["id_fichier"].'" ';
$resultat .= 'nom="'.$BddFichier["nom_fichier"].'" ';
$resultat .= 'taille="'.$BddFichier["taille_fichier"].'" ';
$resultat .= 'type="'.$BddFichier["type_fichier"].'" ';
$resultat .= 'dateDerniereModification="'.$BddFichier["datedernieremodification_fichier"].'" ';
$resultat .= 'autorisation="'.$BddFichier["autorisation_fichier"].'" ';
$resultat .= 'etat="'.$BddFichier["etat_fichier"].'" ';
$resultat .= 'createur="'.$BddFichier["id_user"].'" ';
$resultat .= '/>';

}
}
return $resultat;
}
function checkEnregistrement($table, $id)
{
global $db;
$requete = "SELECT * FROM $table WHERE id_$table='$id'";
$stmt = $db->prepare($requete);
$stmt->execute();
if ($stmt->rowCount() == 1)
{
return $stmt->fetch(PDO::FETCH_ASSOC);
}
else
{
return null;
}
}
?>


Si vous avez quelques suggestions que se soit algorithmique ou code je suis prenneur

Merci d'avance

(si besoin est, je peux réexpliquer^^)

4 réponses

syndrael Messages postés 2378 Date d'inscription lundi 4 février 2002 Statut Membre Dernière intervention 29 décembre 2012 20
11 mars 2010 à 13:28
D'abord je passerai par DomDocument, et XPath.. sans oublier une DTD pour naviguer plus rapidement dans ma structure.
S.
3
Perecastorr Messages postés 39 Date d'inscription lundi 10 novembre 2008 Statut Membre Dernière intervention 7 septembre 2010 1
11 mars 2010 à 15:27
Ok pour le principe du DOM, mais ici je doit parcourrir tout le XML donc autant utiliser un parseur XML non ? la librairie simple_xml marche très bien dans mon cas...
Et btw j'ai trouver la solution a mon problème algorithmique en pseudo code sa donne :
pour chaque dossier racine
{
ecriture balise debut
fonction parcourrir(neud xml racine, idDossier)
ercriture fin balise
}

fonction parcourir(neud xml, idDossier)
{
ListerIdDossiers de la BDD(idDossier)
if(neud xml != null)
{
pour chaque  element dossier
{
enleve de la liste de dossier BDD
ecriture debut balise
parcourir(noeud xml dossier, idElement )
ecriture fin balise
}
}
pour chaque element de la liste
{
ecrire debut balise
parcourir( null, idElement );
ecriture fin balise
}
if(neud xml != null)
{
pour chaque fichier
{
recuperation details
ecriture balise
}
}
}
3
Perecastorr Messages postés 39 Date d'inscription lundi 10 novembre 2008 Statut Membre Dernière intervention 7 septembre 2010 1
11 mars 2010 à 13:40
Il est vrai que mon code est complétement sale et très peu otpimisé. Je retiens fortement l'idée du DOM et du Xpath (la DTD est déja faite) mais pour l'instant j'aimerai gardé ce code crado (mais que tout le monde peut comprendre) pour résoudre les problèmes algorithmique
Le problème le plus urgent c'est que mon code renvoie bien la correspondance des fichiers avec leur détails (valeur1, valeur2) mais ne renvoi pas les dossier qui sont présent dans la Base de données mais pas dans le XML d'entré.
Pour ce problème il me faut modifié mon algorithme recursif mais je n'arrive pas a trouvé le bon endroit et surtout la logique a appliquer.

J'ai pensé a 2 ou 3 solutions :
- Dans la fonction "parcourrirDossier" remplacer la source de la premiere boucle foreach par la base de données(au lieu du XML d'entré comme avant) mais je ne peux plus continué ma récursivité
- Changer totalement la structure : parcourrir en premier le XML et récupérer les id des fichiers présent puis parcourrir recursivement la base de données pour écrire le XML en vérifiant que les fichiers n'ont pas été lister precedement. Mais cette solution me fais parcourrir entièrement CHAQUE document et ce n'est pas vraiment optimisé

Même si vos suggestions sont en pseudo-code cela me va!
0
syndrael Messages postés 2378 Date d'inscription lundi 4 février 2002 Statut Membre Dernière intervention 29 décembre 2012 20
11 mars 2010 à 15:05
Excuse moi mais j'ai peu de temps et je n'ai lu que les 2-3 premières lignes.. si tu réponds à ma proposition dèjà c'esrt pas grave..
Pourquoi DOM ? Tout simplement pour GetElementsByTagName sur Dossier et Fichier, une fois que cette entrée est isolé tu recherche via XPath la sortie correspondante pour lui faire un setAttribute des différentes valeurs..
S.
0
Rejoignez-nous