Bonjour à tous,

Je suis en train de faire un petit formulaire pour supprimer des noeuds sur un fichier XML. Pour cela je liste chaque noeuds dans une checkbox. Grâce à ça, l'utilisateur pourra cocher un ou plusieurs noeud et les supprimer en un seul clic sur le bouton submit.

Lors de la réception du formulaire en POST, je récupère les "id" de chaque noeud. Leur ordre en fait (pas d'attributs dans les balises).
Par exemple si j'ai coché le 1er noeud et le 3e, j'aurais en POST les valeur 0 et 2.

De là, j'utilise la classe DOMDocument pour supprimer les noeuds grâce à sa méthode removeChild.
Et donc pour les supprimer, je fais une boucle qui va jusqu'à 20 (car il n'y aura jamais plus de 20 noeuds) et à l'intérieur je fais un test : si mon compteur est égale à la valeur du POST alors je supprime le noeud ayant cette valeur.

Vous me suivez toujours ? ^^

Le problème est que durant la boucle, quand il va supprimer un noeud, cela va du coup décaler la position des autres de -1 pour le passage suivant de la boucle.
Par exemple il y a 4 noeuds, je supprime le noeud 0, le noeud 1 devient donc le noeud 0, le 2 devient le 1, etc... Du coup à l'autre passage de la boucle, si je voulais supprimer le noeud 2, il va en fait supprimer le noeud 3.

Et cela fausse par conséquent tout le reste de ma boucle...
Quelqu'un aurait une idée où une autre façon de faire ? Merci à vous.

Voilà mon code:
Le formulaire :

<?php
$xml = simplexml_load_file('job.xml');
$nbNode = count($xml);
?>
<form method='post' action='manage_job.php'>

  <?php for($i=0; $i<$nbNode; $i++)
    {
?>
             <p><input type="checkbox" id="test<?php echo $i; ?>" name="titre<?php echo $i; ?>" value="<?php echo $i; ?>"/><label for="test<?php echo $i; ?>"><span class="ui"></span><?php echo $xml->job$i]->titre; ?></label></p>
  <?php } ?>

              <input type="submit" name="deleteJob" value="» Supprimer le job"/>
</form>

La Réception du formulaire:

$doc = new DOMDocument();
$doc->load('job.xml');
$book = $doc->documentElement;

for($i=0; $i<20; $i++)
{
    if(isset($_POST"titre$i"]))
    {
        $job = $doc->getElementsByTagName('job')->item($_POST"titre$i"]);
        $book->removeChild($job);
    }
}

$doc->save("job.xml");

Le XML :

<?xml version="1.0" encoding="UTF-8"?>
<jobs>
    <job>
        <urgent></urgent>
        <titre>zifdjiezjf e</titre>
        <accroche>zifdjiezjf ezifdjiezjf e</accroche>
        <descriptif>zifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf e </descriptif>
        <ville>zifdjiezjf e</ville>
        <contact>zifdjiezjf ezifdjiezjf ezifdjiezjf e</contact>
    </job>
        <job>
        <urgent></urgent>
        <titre>zifdjiezjf e</titre>
        <accroche>zifdjiezjf ezifdjiezjf e</accroche>
        <descriptif>zifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf e </descriptif>
        <ville>zifdjiezjf e</ville>
        <contact>zifdjiezjf ezifdjiezjf ezifdjiezjf e</contact>
    </job>
        <job>
        <urgent></urgent>
        <titre>zifdjiezjf e</titre>
        <accroche>zifdjiezjf ezifdjiezjf e</accroche>
        <descriptif>zifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf e </descriptif>
        <ville>zifdjiezjf e</ville>
        <contact>zifdjiezjf ezifdjiezjf ezifdjiezjf e</contact>
    </job>
        <job>
        <urgent></urgent>
        <titre>zifdjiezjf e</titre>
        <accroche>zifdjiezjf ezifdjiezjf e</accroche>
        <descriptif>zifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf ezifdjiezjf e </descriptif>
        <ville>zifdjiezjf e</ville>
        <contact>zifdjiezjf ezifdjiezjf ezifdjiezjf e</contact>
    </job>

</jobs>

4 réponses


Bonjour,
pas super optimisé (voir même pas du tout XD)

deux boucles, la première tu stockes les $job a supprimer dans je sais pas un tableau par exemple
Puis tu boucles sur le tableau pour les supprimer.

Mousse
Auteur

Ah moins que j'ai mal saisi, ce que je fais reviens au même. Les jobs sont stockés dans $_POST qui est deja un tableau (bon je sais en réalité ce n'en est pas un mais là ça revient au même xD).

Dans ta méthode, ça ne marchera pas non plus étant donné que tu boucles sur le tableau, cela va faire exactement comme ma méthode :

  • Premier passage de la boucle : il supprime le premier job, le job suivant prend la place de celui supprimé (et donc son index change et tous les suivants aussi)
  • Deuxieme passage de la boucle : il va supprimer le second job mais son index a changé du coup il ne supprimera pas le bon
  • etc...

Tu vois ce que je veux dire ?

Je viens de comprendre le problème, j'avais lu un peu vite.
Et si tu fais ta boucle dans l'autre sens??

Admettons tu as tes élements:

1
2
3
4

tu veux virer 2 et 3

Si tu parcours a lenvers:

Tu vires d'abord 3, il reste

1
2
4

tu vires ensuite 2 qui est bien le 2eme, la liste étant décalé sur les éléments déjà traité non ?

Mousse
Auteur

C'est bien pensé ! Je vais essayé ça dès que je peux.