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

Windows Forms Discussion :

[C#] [XML] Insérer un noeud entre un parent et ses enfants


Sujet :

Windows Forms

  1. #1
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut [C#] [XML] Insérer un noeud entre un parent et ses enfants
    bonjour,

    j'espere ne pas me tromper de forum, j'ai hésité avec le forum XML mais c'est plus une question sur la fonction à utiliser.

    J'ai une structure xml de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <A>
      <B>
      </B>
      <C>
      </C>
    </A>
    Je voudrais insérer un noeud qui se placerait entre A et ses enfants; comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <A>
      <NEW>
        <B>
        </B>
        <C>
        </C>
      </NEW>
    </A>
    Je ne travaille pas sur un fichier xml "physique", mais sur du code xml stoqué dans un string.

    Voici ce que j'ai fais pour l'instant:
    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
    object missing = System.Reflection.Missing.Value;
    StringReader sr;
    StringWriter sw= new StringWriter();
    XmlTextWriter xw;
    XmlDocument xmlDoc;
    XmlElement elem;
    sr=new StringReader(xml); //xml est un string qui contient le code xml
    xmlDoc = new XmlDocument();
    xmlDoc.Load(sr);
    XmlNodeList nodeLst=xmlDoc.GetElementsByTagName("A");
    foreach(XmlNode node in nodeLst)
    {
       elem = xmlDoc.CreateElement("NEW");
       node.InsertAfter(elem, node.FirstChild);
       xw = new XmlTextWriter(sw);
       xmlDoc.WriteTo(xw);
       MessageBox.Show(sw.ToString());
    }
    Le problème est que celà rajoute le nouveau noeud apres et pas entre, et je ne vois aucunes méthode pour ajouter un noeud entre 2... quelqu'un a une ?

    Merci,

    Frenchy

  2. #2
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    Ca fait trop longtemps que je suis dessus, rien ne fonctionne.

    La dernier chose que j'ai éssayé c'est de copier le noeud principal et ses enfants[CloneNode(true)], puis de retirer tous ses enfants[RemoveAll()], de rajouter mon noeux[PrependChild(elem)], jusque là ca a fonctionné.

    Apres j'éssaye de recopier les enfants que j'avais copié dans le noeud temporaire mais ca ne fonctionne pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    foreach(XmlNode nooooode in temp.ChildNodes)
    {
    node.FirstChild.AppendChild(nooooode);
    }
    Il ne fait qu'une et une seule fois la boucle meme s'il y a 10 enfants(vérifié avec la propriété count sur childnodes)
    ...Donc je m'y prends forcement mal, mais quelle est la technique à utiliser?

    Aidez-moi svp, je commence à peter un cable

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 83
    Points : 107
    Points
    107
    Par défaut
    Salut,

    tu peux essayer quelque chose de ce style (en utilisant un tableau)

    Ex:

    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
     
    XmlDocument d = new XmlDocument(); 			
     
    // Charger le document
    d.Load(@"F:\Decharge\fichier.xml");
     
    // Positionner sur le noeud à partir duquel inserer
    XmlNode root = d.SelectSingleNode("//A");
     
    // Création tableau de XmlNode
    XmlNode[] copy = new XmlNode[root.ChildNodes.Count];
    int i=0;
    foreach(XmlNode x in root.ChildNodes)
    {
    	copy[i] = x.Clone();
    	i++;
     
    }
     
    // Création du nouvel element
    XmlElement element = d.CreateElement("NEW");
     
    // Suppression des noeuds clonés
    root.RemoveAll();
     
    // Ajout du noeud crée et des noeuds clonés
    XmlNode nwNode = root.AppendChild(element);
    for(i=0;i<copy.Length;i++)
    {
    	nwNode.AppendChild(copy[i] );
    }
     
    // Sauvegarde du document
    d.Save(@"F:\Decharge\fichier.xml");
    En esperant que cela puisse t'aider

  4. #4
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    J'éssaye de suite, merci pour ta réponse

  5. #5
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    Malheureusement il y a un problème avec XPath, je ne comprends pas bien à quoi il sert, je pense que c'est pour faire des recherches,sélections...

    Voici l'erreur:
    System.Xml.XPath.XPathException: Le gestionnaire d'espaces de noms ou XsltContext est requis. Cette requête a un préfixe, une variable ou une fonction définie par l'utilisateur.
    at System.Xml.XPath.CompiledXpathExpr.get_QueryTree()
    at System.Xml.XPath.XPathSelectionIterator..ctor(XPathNavigator nav, XPathExpression expr)
    at System.Xml.XPath.XPathNavigator.Select(String xpath)
    at System.Xml.XmlNode.SelectNodes(String xpath)
    at System.Xml.XmlNode.SelectSingleNode(String xpath)
    L'erreur correspond à cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    XmlNode root = xmlDoc.SelectSingleNode("//w:p");
    ...oui mon noeud s'apelle <w:p> et non <A> mais ca ne change rien.

    Comme je l'ai dit, je travaille avec un fichier XML en mémoire.

    Je remets tout le code pour que vous compreniez mieux
    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
    object missing = System.Reflection.Missing.Value;
    string xml=...tout mon code xml...;
    StringReader sr;
    StringWriter sw= new StringWriter();
    XmlDocument xmlDoc;
    try
    {
      sr=new StringReader(xml);
      xmlDoc = new XmlDocument();
      xmlDoc.Load(sr);
      XmlNode root = xmlDoc.SelectSingleNode("//w:p"); 
      XmlNode[] copy = new XmlNode[root.ChildNodes.Count]; 
      int i=0; 
      foreach(XmlNode x in root.ChildNodes) 
      { 
        copy[i] = x.Clone(); 
        i++; 
      } 
      XmlElement element = xmlDoc.CreateElement("NEW"); 
      root.RemoveAll(); 
      XmlNode nwNode = root.AppendChild(element); 
      for(i=0;i<copy.Length;i++) 
      { 
        nwNode.AppendChild(copy[i] ); 
      } 
      xmlDoc.Save(sw);
    }
    PS: pour l'instant j'éssaye de le faire pour un noeud, mais if faut savoir que plus tard je devrai le faire pour chaque noeud, je supose qu'avec xpatch je peux sélectionner tous les noeuds <w:p>

    Si ce que je veux faire est trop compliqué, peut êter devrai-je alors me tourner vers le traitement du String, càd insérer apres <w:p> <new> et avant </w:p> </new>. En faisant un traitement sur la chaine de caratere ca sera beaucoup plus simple, mais je trouve stupide de ne pas utiliser les fonctions XML... ou alors c'est moi qui suis stupide :

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 83
    Points : 107
    Points
    107
    Par défaut
    Désolé,

    je ne suis pas un spécialiste du XML, mais il me semble que que le nom de balise <w:p> ne soit pas valide en XML (en effet le ":" doit avoir une signification particulière ??? ).

    rapproche toi du forum xml

    Bonne chance

  7. #7
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    voilà suite du post ici:http://www.developpez.net/forums/vie...789797#1789797

    Sorry pour le double post, mais je n'ai pas le choix,...je dois trouver une solution

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 83
    Points : 107
    Points
    107
    Par défaut
    Bonjour,

    suite à ton post et après renseignements, il semble que les ":" dans ta balise fasse référence à un espace de nom au niveau de la déclaration du fichier xml

    Ton fichier XML doit avoir cette forme (wordml)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <?xml version="1.0"?>
    <w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml">
      <w:body>
        <w:p>
          <w:r>
           <w:t>TEST</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:wordDocument>
    Le code fait précedemment doit fonctionner à partir ou tu adjoint un
    namespacemanager à ton document.

    Le code devrait ressembler à ceci (en se basant sur la structure du fichier XML dfini précedemment) :

    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
    38
    39
    40
     
     
    // Insertion d'un noeud en XML
    XmlDocument d = new XmlDocument(); 			
     
    // Charger le document
    d.Load(@"F:\Decharge\fichier.xml");
     
    // utilisation d'un namespacemanager
    XmlNamespaceManager nsm = new XmlNamespaceManager(d.NameTable);
    nsm.AddNamespace("w" , "http://schemas.microsoft.com/office/word/2003/wordml");
     
     
    // Positionner sur le noeud à partir duquel inserer
    XmlNode root = d.SelectSingleNode("//w:r",nsm); // Utilisation du namespacemanager
    XmlNode[] copy = new XmlNode[root.ChildNodes.Count];
     
    // Création tableau de XmlNode
    int i=0;
    foreach(XmlNode x in root.ChildNodes)
    {
                copy[i] = x.Clone();
                  i++;
    }
     
    // Création du nouvel element
    XmlElement element = d.CreateElement("NEW22222");
     
    // Suppression des noeuds clonés
    root.RemoveAll();
     
    // Ajout du noeud crée et des noeuds clonés
    XmlNode nwNode = root.AppendChild(element);
    for(i=0;i<copy.Length;i++)
    {
    	nwNode.AppendChild(copy[i] );
    }
     
    // Sauvegarde du document
    d.Save(@"F:\Decharge\fichier.xml");

  9. #9
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    Pour quelqu'un qui ne s'y connait pas en xml, je te dis un grand merci.

    Ton code a fonctionné du 1er coup, bravo!

    puis-je savoir où tu as trouvé l'information?


    Encore merci,

    Frenchy

  10. #10
    Membre confirmé
    Avatar de frechy
    Inscrit en
    Novembre 2004
    Messages
    343
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Novembre 2004
    Messages : 343
    Points : 511
    Points
    511
    Par défaut
    Pour quelqu'un qui ne s'y connait pas en xml, je te dis un grand merci.

    Ton code a fonctionné du 1er coup, bravo!

    puis-je savoir où tu as trouvé l'information?


    Encore merci,

    Frenchy

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 83
    Points : 107
    Points
    107
    Par défaut
    Ravi que ton problème soit résolu

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

Discussions similaires

  1. [XPATH 1.0] Référence au noeud courant, pour en récupérer ses enfants directs
    Par Lcf.vs dans le forum XSL/XSLT/XPATH
    Réponses: 12
    Dernier message: 25/03/2015, 10h13
  2. Xml insérer dans un noeud spécifique
    Par Ashiteru dans le forum VB.NET
    Réponses: 1
    Dernier message: 08/02/2013, 11h08
  3. Réponses: 5
    Dernier message: 12/11/2010, 09h45
  4. [VB6] TreeView -- faire la différence entre le parent et l'enfant
    Par Baquardie dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 22/10/2004, 22h16

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