IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques et frameworks PHP Discussion :

[DOM] Ajouter un noeud dans un XML existant


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut [DOM] Ajouter un noeud dans un XML existant
    Bonjour tout le monde

    Pour mes cours je doit développer une application php, permettant d'ajouter/modifier/supprimer des noeud XML depuis un fichier existant, j'arrive à lire un fichier XML sans problème avec SimpleXML, mon problème ce situe lors de l'ajout, j'ai lu qu'avec SimpleXML il était tout simplement impossible d'ajouter un noeud, mon problème est que je n'y arrive pas avec l'API DOM snif

    Voici le fichier XML ( très basique )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <repertoire>
      <personne id="1">
        <nom>un nom</nom>
      </personne>
    </repertoire>
    j'ai donc une page contenant un simple input texte pour ajouter un nom, mais impossible de modifier le fichier XML existant en ajoutant un noeud <personne>, voici ce que je fait en PHP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    $dom = new DomDocument();
    $dom->load('test.xml');
    if($dom->validate()){
      echo "document valide<br />";
      // on crée le nouveau noeud
      $newPersonne = $dom->createElement("personne");
      // on ajoute l'attribut id à <personne>
      $newPersonne->setAttribute("id", "2");
      // on crée le noeud textuel
      $nomPersonne = $dom->createTextNode($_POST['nom']);
     
      $newPersonne->appendChild($nomPersonne);
     
      $dom->save('test.xml');
    Je doit être complètement à coter de la plaque car rien ne ce produit, le fichier n'est pas modifier et aucun message d'erreur ( meme avec le report d'erreur php sur E_ALL).
    quelqu'un pourrait-il m'expliquer comment je peux enregistré le noeud <personne> contenant l'élément <nom> à la suite de mon fichier XML

    d'avance merci de votre aide, je débute avec XML et PHP et vous prie de m'excuser si ce genre de message à déjà été poster

  2. #2
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    salut
    essaye ça, j'ai rajoute " $dom->appendChild($newPersonne);" avant de sauver.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $dom = new DomDocument();
    $dom->load('test.xml');
    if($dom->validate()){
      echo "document valide<br />";
      // on crée le nouveau noeud
      $newPersonne = $dom->createElement("personne");
      // on ajoute l'attribut id à <personne>
      $newPersonne->setAttribute("id", "2");
      // on crée le noeud textuel
      $nomPersonne = $dom->createTextNode($_POST['nom']);
     
      $newPersonne->appendChild($nomPersonne);
     
      $dom->appendChild($newPersonne);
     
      $dom->save('test.xml');

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Pour SimpleXML c'est possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $sxml = simplexml_load_file('test.xml');
    $personne = $sxml->addChild('personne');
    $personne->addAttribute('id', '2');
    $nom = $personne->addChild('nom', /*utf8_encode*/($_POST['nom']));
    $sxml->asXML('test.xml');
    Avec DOM :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $dom = new DomDocument();
    $dom->load('test.xml');
    $personne = $dom->createElement('personne');
    $personne->setAttribute('id', '2');
    $nom = $dom->createElement('nom', /*utf8_encode*/($_POST['nom']));
    $personne->appendChild($nom);
    $dom->documentElement->appendChild($personne);
    $dom->save('test.xml');
    Il y a avait quelques petites erreurs : vous ne créiez pas l'élément nom et l'élément référent lors d'un ajout (méthode appendChild) est son père.

    (non testé)

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut
    merci à vous deux pour vos réponse, j'ai vue et compris ou était mes erreurs grâce à vous et ca devient de suite plus clair, voir même plus logique, celà fonctionne parfaitement maintenant

    par contre je ne savais pas que c'était fesable avec SimpleXML on m'a toujours dit que c'était impossible, pourtant ca fonctionne bien aussi.

    mille merci à vous

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut
    temps que je suis dans l'élant

    est-il possible de modifier et supprimer un noeud avec SimpleXML ?
    puis-je modifier une personne par apport à l'attribut id de personne ?

    donc j'ai une liste de nom, je clic sur editer et hop le formulaire pour modifier celui-ci ?
    idem pour la suppresion ?

    d'avance encore merci de votre aide

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Oui, avec DOM comme avec SimpleXML (mais dans ce dernier cas il me semble que la version de PHP est à prendre en compte).

    Un exemple pour la modification (réaliser dans le bloc else) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <?php
    $sxml = simplexml_load_file('test.xml');
     
    if ($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_POST['personne'])) {
    ?>
     
    <form method="POST">
        Personne :
        <select name="personne">
    <?php
    foreach ($sxml->personne as $p) {
        printf('<option value="%d">%s</option>', $p['id'], $p->nom);
    }
    ?>
        </select>
        <br />
        <input type="submit" value="Valider" />
    </form>
     
    <?php
    } else if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST['personne']) && empty($_POST['nom'])) {
    ?>
     
    <form method="POST">
        Nouveau nom : <input type="text" name="nom" />
        <br />
        <input type="submit" value="Valider" />
        <input type="hidden" name="personne" value="<?php echo $_POST['personne']; ?>" />
    </form>
     
    <?php
    } else {
        $res = $sxml->xpath(sprintf('/repertoire/personne[@id = "%d"]', $_POST['personne']));
        $res[0]->nom = utf8_encode($_POST['nom']);
        header('Content-type: text/plain');
        echo $sxml->asXML();
    }
    La suppression se réalise de la même manière : une fois le noeud ciblé, il suffit de fournir l'objet SimpleXMLElement correspondant à la fonction unset.

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut
    merci beaucoup, j'ai compris la méthode à suivre pour enregistré la modification
    seulement dans ton exemple, tu le met dans un liste déroulante, moi quand j'ai un tableau avec la liste des nom de type

    nom1 | Modifier | Supprimer
    nom2 | Modifier | Supprimer

    Modifier | Supprimer sont des liens, et passe en variable GET l'attribut id de personne ca donne comme lien "index.php?op=edit&amp;id=1" pour le premier par exemple.

    donc quand je clic sur le lien j'arrive sur la case edit() avec le paramètre $_GET['id'] me fournissant l'id à modifier et tombe sur l'input type text mais contenant déjà le nom ( qui doit être modifier ), j'ai donc temps bien que mal essayer de modifier et j'ai ceci dans case edit();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $sxml = simplexml_load_file('test.xml');
    $personneCible = $sxml->personne->xpath('/repertoire/personne[@id = "' . $_GET['id'] . '"]');
    $nom = $personneCible->nom;
    echo "<form id=\"edit\" method=\"post\" action=\"index.php?op=saveEdit&amp;id=" . $_GET['id'] . "\">\n"
       . "Modifier le nom --> <input type=\"text\" name=\"nom\" value=\"" . $nom . "\" /> <input type=\"submit\" name=\"send\" value=\"OK\" />\n"
       . "</form>\n";
    mais je doit avoir un problème avec l'XPATH que je doit pas vraiment définir correctement, puisque rien ne s'affiche dans l'input comme valeur par defaut, alors que je voudrai qu'il m'affiche dans l'input comme valeur par défaut le nom actuel ( avant la modif ), je sais si c'est clair ce que je raconte.

    et enfin ma case saveEdit();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $sxml = simplexml_load_file('test.xml');
    $res = $sxml->xpath(sprintf('/repertoire/personne[@id = "%d"]', $_GET['id']));
    $res[0]->nom = utf8_encode($_POST['nom']);
    header('Content-type: text/plain');
    echo $sxml->asXML();
    La pas de souci il remplace bien le nom par celui introduit dans l'input, mais je ne comprend pas à quoi correspond le %d

    je vous en demande beaucoup, et je vous remercie franchement pour tout ce que vous faite pour m'aider

    ps : si vous vous demandez pourquoi je veux l'afficher dans un input, c'est parceque je n'ai pas que <nom> dans <personne> ici j'ai simplifier pour moi comprendre, et j'ai pu appliquer l'ajout de noeud et d'élément à tout le contenu donc maintenant je m'attel à la modification et après à la suppression mais tous ce fait via une variable GET['id'] qui est l'id de <personne>

    encore merci mille fois

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Activez bien l'affichage de toutes les erreurs : la méthode xpath retourne un tableau. Par conséquent, cette écriture serait plus "juste" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom = $personneCible[0]->nom;
    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom = $personneCible->nom;
    Cependant, il faudrait éventuellement tester le résultat de cette méthode car elle pourrait ne pas retourner de résultat ou échouer (cas à évaluer et qui pourrait se présenter suite à un accès concurrent aux données ou à une saisie manuelle de l'identifiant dans l'URL).

    En ce qui concerne l'option de formatage %d (associée à la fonction sprintf) : c'est simplement une habitude de ma part pour avoir un code plus lisible, qui permet aussi d'éviter les casts que l'on emploie souvent dans le cadre des requêtes SQL pour éviter les injections. Si vous préférez, vous pouvez remplacer cette écriture par une concaténation (c'est ce que vous avez fait dans votre premier code) voir une interpolation (ie : "/repertoire/personne[@id = '{$_GET['id']}']").

  9. #9
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut
    oui oui Activez bien l'affichage de toutes les erreurs, c'est même devenu sistématique en mode codage.

    merci pour vos explication, effectivement une fois coder
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $nom = $personneCible[0]->nom;
    celà fonctionne parfaitement, le champ affiche le nom par défaut et la fonction saveEdit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $res = $sxml->xpath('/repertoire/personne[@id = "' . $_GET['id'] . '"]');
    fonctionne parfaitement aussi, merci beaucoup

    il ne me reste plus qu'a pouvoir supprimer un noeud, pour ce faire j'ai une case delete(); qui comme pour l'edition récupère la variable $_GET['id'] j'ai donc essayer d'utiliser unset mais rien n'est supprimer je suppose encore un problème de ciblage, voici le code actuel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $sxml = simplexml_load_file('test.xml');
    $personneCible = $sxml->personne->xpath('/repertoire/personne[@id = "' . $_GET['id'] . '"]');
    unset($personneCible[0]);
    header('Content-type: text/plain');
    echo $sxml->asXML();
    je me suis dit que je devais utiliser le même principe de ciblage que pour la modification soit : $personneCible[0]
    Mais apparament je doit encore faire une erreur

    Je doit ptet vous soulez avec mes merci mais c'est une question de principe et de respect, donc je vous dit encore merci de votre aide

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Désolé, en fait il faut écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unset($personneCible[0][0]);
    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unset($personneCible[0]);

  11. #11
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 274
    Points : 114
    Points
    114
    Par défaut
    houraaa ca fonctionne :p grâce à vous je peux Ajouter/modifier/Suprrimer un noeud

    j'ai toute fois encore une toute petite question
    pour la suppression nous devons utiliser
    $personneCible[0][0]
    Alors que pour la modification nous utilison
    $personneCible[0]
    pourtant c'est exactement la même manipulation pour la modification et pour la suppression, pourriez-vous m'expliquer pourquoi nous avons du rajouter une clé [0] pour la suppression et pas pour la modification ?

    Voilà c'est ma toute dernière question, après ce sujet sera résolut grâce à vous et vous en remercie encore

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Je l'ignore mais cela semble propre à la fonction unset pour un résultat d'une expression XPath. Cela peut être dû à la manière dont sont représentés en interne les éléments (les développeurs ont pu reprendre la structure du document, c'est à dire que chaque élément du résultat pourrait être plus complexe qu'il n'y paraît au sens que l'objet SimpleXMLElement ne correspondrait pas directement à un élément. Pour illustrer, prenez l'exemple de $sxml->personne qui représente l'ensemble des éléments personne, fils de la racine).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XMLBEANS] Surfer et ajouter des noeuds dans mon XML
    Par akrogames dans le forum APIs
    Réponses: 0
    Dernier message: 05/12/2010, 17h16
  2. Ajouter un noeud à un fichier xml existant
    Par babou54 dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 14/04/2009, 16h54
  3. ajoutter un noeud dans un xml existant
    Par etud_ini dans le forum VB.NET
    Réponses: 1
    Dernier message: 26/10/2008, 20h08
  4. [DOM] Ajouter un noeud dans un noeud défini
    Par Hombre dans le forum Bibliothèques et frameworks
    Réponses: 8
    Dernier message: 15/05/2006, 19h48
  5. [DOM] PHP5 et XML comment ajouter un noeud dans un noeud précis?
    Par titou250 dans le forum Bibliothèques et frameworks
    Réponses: 12
    Dernier message: 20/04/2006, 21h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo