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

Framework .NET Discussion :

[Linq To XML] Modifier l'objet, le xml ?


Sujet :

Framework .NET

  1. #1
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut [Linq To XML] Modifier l'objet, le xml ?
    Bonjour,

    Je débute totalement avec Linq.

    J'ai un tout petit fichier xml de paramètre, j'aimerai utiliser Linq pour le mettre dans un objet, afin de modifier la structure, puis re-générer le nouveau fichier xml.

    Par exemple, voici ce que j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <XML>
        <Produits>
            <Produit> (des attributs)
                <Nom>
                    leNom
                </Nom>
            </Produit>
        </Produits>
     </XML>
    Voici ce que je veux :
    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
    <XML>
        <Produits>
            <Produit> (des attributs)
                <Nom>
                    leNom
                </Nom>
                <NouveauNoeud>
                    <QuiContiendraDesNoeuds>
                        blabla
                    </QuiContiendraDesNoeuds>
                </NouveauNoeud>
            </Produit>
        </Produits>
     </XML>
    Donc l'idée c'est d'utiliser Linq pour simplifier l'opération.

    Merci

  2. #2
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    XElement xml = XElement.Load("monfichier.xml");
     
    //1er produit
    XElement produit = xml.Element("Produits").Elements("Produit").First(); 
     
    //création du nouveau noeud
    XElement nouveau = new XElement("NouveauNoeud",
        new XElement("QuiContiendraDesNoeuds", " blabla")
    );
     
    produit.Add(nouveau);
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  3. #3
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    Il y a un problème, mon objet est null.

    J'ai éclaté la ligne de code pour voir d'où ça viens.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    XElement produits = xml.Element("Produits");// produits est null
    Alors que xml se rempli bien (d'ailleur c'est excellent)

    Je ne maitrise pas trop, le nom que je passe est bien le noeuds qui contient les autres (qui est sous le noeud "xml")

    Merci, je vais chercher encore, ça à l'air d'être pas trop compliqué

    Bon en fait, ça à l'air simple... mais je comprend toujours pas pourquoi mon objet est vide.
    pourtant si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                object produits = from p in xml.Descendants("produit")
                                    select p;
    mon objet possède un tableau de résultat des noeuds qui m'interresse, dans "Results View" (si j'utilise un objet, c'est que je suis même pas certain de savoir ce que je récupère !)

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Ticoche Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                object produits = from p in xml.Descendants("produit")
                                    select p;
    mon objet possède un tableau de résultat des noeuds qui m'interresse, dans "Results View" (si j'utilise un objet, c'est que je suis même pas certain de savoir ce que je récupère !)
    Tu récupères un XElement (XElement.Descendants renvoie un IEnumerable<XElement>). Dans le doute, tu peux mettre le type "var".

  5. #5
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    Je n'y arrive toujours pas.

    Comment faire, si maintenant je veux lire le contenu blabla dans le noeud QuiContiendraDesNoeuds ?

    Merci

    édit:
    Un exemple. J'aimerai récuperer l'attribut (id) d'un produit pour lequel le noeud nom contient "toto". Comment se passe la requete en Linq ?

    <produit id=1>
    <nom>tata</nom>
    </produit>
    <produit id=2>
    <nom>toto</nom>
    </produit>

    Je récupère donc 2

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Essaye un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    from p in doc.Descendants("produit")
    let line = p
    where p.Element("nom").ToString().Contains("toto")
    select p.Attributes("id");
    Attention, je te garantie pas la syntaxe car j'ai rien pour testé

  7. #7
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    J'ai réussis à obtenir le bon résultat en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
                foreach (var nodeMarchand in xml.Elements("marchands").Elements("marchand"))
                {
                    foreach (var nodeRepertoire in nodeMarchand.Elements("repertoire"))
                    {
                        if (nodeRepertoire.Value == rep)
                        {
                            locale = (vendor_id)Convert.ToInt32(nodeMarchand.Attribute("vendor_id").Value);
                        }
                    }
                }
    vendor_id est un enum.

    alors que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                var query = from p in xml.Descendants("marchand")
                    let line = p
                    where p.Element("repertoire").ToString().Contains(rep)
                    select p.Attributes("vendor_id");
    me donne Null.
    (les noeuds n'ont pas le même nom que dans mon exemple, mais c'est tout pareil)

    Du coup, j'aimerai quand même réussir à utiliser une requete linq pour obtenir le même résultat, ça à l'air plus simple... quand on comprend ?!

  8. #8
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Essaye de remplacer:

    select p.Attributes("vendor_id");


    Par:

    select line.Attributes("vendor_id");

  9. #9
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    J'ai essayé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                var query = from p in xml.Descendants("marchand")
                            let line = p
                            where p.Element("repertoire").ToString().Contains(rep)
                            select line.Attributes("vendor_id");
    Je penses que c'est bon, en debug quand je développe l'objet query j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    query
        + Results View
            + [0]
                + Results View
                    + [0] {vendor_id="8"}
    ¿ Maintenant... comment récupérer le fameux "8" ?

    édit: Sinon qu'est-ce que c'est : let line = p ?

  10. #10
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    met ca et ca devrait marcher:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var query = from p in xml.Descendants("marchand")
                            let line = p
                            where p.Element("repertoire").ToString().Contains(rep)
                            select line.Attributes("vendor_id").Value;

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Ticoche Voir le message
    édit: Sinon qu'est-ce que c'est : let line = p ?
    Sauf erreur de ma part, dans un cas comme ça il ne sert à rien... (ça fait juste un alias de p appelé line)

  12. #12
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    Bonjour,

    Dans la suite des choses, comment faire pour :
    1) créé un nouvel attribut sur un noeud et lui affecter une valeur
    ou
    2) affecter une valeur à une attribut déjà existant ?

    Merci

    PS : je n'arrive toujours pas à ajouter un noeud, comme expliqué dans mon 1er post, grace à Linq

    édit:
    avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                XDocument xml = XDocument.Load("params.xml");
                XElement marchands = xml.Element("marchands");
     
                StringBuilder dateHeure = new StringBuilder(DateTime.Now.ToLongDateString());
                dateHeure.Append(" à ");
                dateHeure.Append(DateTime.Now.ToLongTimeString());
     
                //création d'un attribut
                XAttribute maj = new XAttribute("maj", dateHeure);
                marchands.Add(maj);
    j'arrive à voir en mode debug la balise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <marchands maj="lundi 28 avril 2008 à 10:10:02">
    mais quand j'ouvre le fichier, l'attribut n'a pas été mis en place

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Ton XDocument, tu l'enregistres ? Avec la méthode Save ?

  14. #14
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    359
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 359
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Ton XDocument, tu l'enregistres ? Avec la méthode Save ?


    effectivement, maintenant ça fonctionne beaucoup mieux !

    Merci

    édit:

    Bon, la 1ère fois ça passe, après j'ai une erreur Duplicate Attribute, ce qui est normale puisque je veux le créer à chaque fois, je ne sais pas trop comment tester si un attribue existe et le mettre à jour ?

    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
    il y a peu être une manière plus "propre" que de supprimer l'attribue pour le recréer ?
                XDocument xml = XDocument.Load("params.xml");
                XElement marchands = xml.Element("marchands");
    
                StringBuilder dateHeure = new StringBuilder(DateTime.Now.ToLongDateString());
                dateHeure.Append(" à ");
                dateHeure.Append(DateTime.Now.ToLongTimeString());
    
                //création d'un attribut
                XAttribute maj = new XAttribute("maj", dateHeure);
                marchands.Attribute("maj").Remove();
                marchands.Add(maj);
    
                xml.Save("params.xml");
    il y a peu être une manière plus propre que de supprimer l'attribut pour le recréer ?!

    la solution que j'ai pour le moment (j'espère qu'on peut faire mieux)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                try
                {
                    marchands.Attribute("maj").Remove();
                    marchands.Add(maj);
                }
                catch
                {
                    marchands.Add(maj);
                }

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 18/12/2007, 17h40
  2. [XML] [POO] [Classe/Objet]xml
    Par 2xyo dans le forum Langage
    Réponses: 19
    Dernier message: 21/03/2006, 19h00
  3. Envoyer objet en XML
    Par lagaffe34 dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 1
    Dernier message: 14/02/2006, 17h27
  4. [TreeSet][Conseil][XML] Récupérer un objet
    Par leminipouce dans le forum Format d'échange (XML, JSON...)
    Réponses: 9
    Dernier message: 10/01/2006, 09h50
  5. Ouvrages sur les SGBD Objet et XML ?
    Par le_barbu dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 20/10/2005, 10h00

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