Partage
  • Partager sur Facebook
  • Partager sur Twitter

Parsing XML, XDocument et initialisation

Sujet résolu
    2 juin 2011 à 19:41:45

    Bonjour !

    Cela fait quelques jours maintenance que je suis sur ce problème et je désespère ...
    J'espère que quelqu'un pourra me sortir de là !

    Je vous explique : je veux parser un fichier XML et stocker les infos que je récupère dans des objets.
    Pour faire cela, je fais ça :

    public MainViewModel()
            {
                if (IsInDesignMode)
                {
                    // Code runs in Blend --> create design time data.
                }
                else
                {
                    webClient.DownloadStringAsync(new Uri("URL"));
                    webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webclient_DownloadStringCompleted);
                }
            }
    
            void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
            {
                downloadedXml = e.Result;
                XDocument xmlDoc = XDocument.Parse(e.Result);
                TeacherList teacherList = new TeacherList();
    
                XElement theteachers = xmlDoc.Element("teachers");
    
                teacherList.totalResults = int.Parse(theteachers.Element("totalresults").Value);
                teacherList.pageIndex = int.Parse(theteachers.Element("pageindex").Value);
    
                teacherList.teachers = (from teacher in xmlDoc.Descendants("teacher")
                                        select new Teacher()
                                        {
                                            id = int.Parse(teacher.Element("id").Value),
                                            tampon = int.Parse(teacher.Element("tampon").Value),
                                            video = teacher.Element("video").Value,
                                            image = teacher.Element("image").Value,
                                            timezone = int.Parse(teacher.Element("timezone").Value),
                                            firstName = teacher.Element("firstname").Element("value").Value,
                                            nationality = teacher.Element("nationality").Element("value").Value,
                                            country = teacher.Element("country").Element("value").Value,
                                            birthYear = int.Parse(teacher.Element("birthyear").Element("value").Value),
                                            experience = int.Parse(teacher.Element("experience").Element("value").Value),
                                            nbrStudents = int.Parse(teacher.Element("nbrstudents").Element("value").Value),
                                            nbrCourses = int.Parse(teacher.Element("nbrcourses").Element("value").Value),
                                            hobbies = teacher.Element("hobbies").Element("value").Value,
                                            specialization = teacher.Element("specialization").Element("value").Value,
    
                                            otherlanguages = (from language in xmlDoc.Descendants("otherlanguages")
                                                              select new Language()
                                                              {
                                                                  value = language.Element("language").Element("value").Value
                                                              }).ToList<Language>() ,
    
                                            avgeval = int.Parse(teacher.Element("avgeval").Element("value").Value),
                                            availability = int.Parse(teacher.Element("availability").Element("value").Value)
                                        }).ToList<Teacher>();
    
    
                Debug.WriteLine("Total results : " + teacherList.totalResults);
                Debug.WriteLine("Page Index : " + teacherList.pageIndex);
                Debug.WriteLine("New teacher : ");
    
                foreach (Teacher teacher in teacherList.teachers)
                {
                    Debug.WriteLine("   ID : " + teacher.id);
                    Debug.WriteLine("   Tampon : " + teacher.tampon);
                    Debug.WriteLine("   Video : " + teacher.video);
                    Debug.WriteLine("   Image : " + teacher.image);
                    Debug.WriteLine("   Timezone : " + teacher.timezone);
                    Debug.WriteLine("   Nationality : " + teacher.nationality);
                    Debug.WriteLine("   Country : " + teacher.country);
                    Debug.WriteLine("   Birthyear : " + teacher.birthYear);
                    Debug.WriteLine("   Experience : " + teacher.experience);
                    Debug.WriteLine("   NbrStudents : " + teacher.nbrStudents);
                    Debug.WriteLine("   NbrCourses : " + teacher.nbrCourses);
                    Debug.WriteLine("   Hobbies : " + teacher.hobbies);
                    Debug.WriteLine("   Specialization : " + teacher.specialization);
                    Debug.WriteLine("   Other languages : " + teacher.nationality);
    
                    foreach (Language language in teacher.otherlanguages)
                    {
                        Debug.WriteLine("       Language : " + language.value);
                    }
    
                    Debug.WriteLine("Evaluation : " + teacher.avgeval);
                    Debug.WriteLine("Availability : " + teacher.availability);
                }
    
            }
    


    Avec mes objets :

    class TeacherList
        {
            public int totalResults { get; set; }
            public int pageIndex { get; set; }
            public List<Teacher> teachers { get; set; }
    
            public TeacherList()
            {
                teachers = new List<Teacher>();
            }
        }   
    
    
        class Teacher
        {
            public int id { get; set; }
            public int tampon { get; set; }
            public string video { get; set; }
            public string image { get; set; }
            public int timezone { get; set; }
            public string firstName { get; set; }
            public string nationality { get; set; }
            public string country { get; set; }
            public int birthYear { get; set; }
            public int experience { get; set; }
            public int nbrStudents { get; set; }
            public int nbrCourses { get; set; }
            public string hobbies { get; set; }
            public string specialization { get; set; }
            public List<Language> otherlanguages { get; set; }
            public int avgeval { get; set; }
            public int availability { get; set; }
    
            public Teacher()
            {
                otherlanguages = new List<Language>();
            }
        }
    
        class Language
        {
            public string value { get; set; }
        }
    


    Je récupère correctement le XML, je remplis les champs "totalresults" et "pageindex" de mon objet TeacherList MAIS !
    Lorsque je veux remplir ma liste de "Teacher", avec le "from in select", il me pète systématiquement une erreur à la fin des initialisation, avant le "ToList<Language>" ou "ToList<Teacher>" si je commente "otherlanguages" ... Il m'insulte en me disant que teacherList.teachers (ma liste de Teacher quoi) est NULL. J'ai vérifié elle ne l'est pas avant de rentrer dans le "from in select"
    Ceci alors que ma liste est bien initialisée dans son constructeur ... Je ne comprends pas ...

    A l'aaaaaaaaaiiiiiiiiiiide !

    Merci d'avance :)
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      2 juin 2011 à 20:30:14

      Trois trucs en voyant ton code :
      -A quoi sert la classe TeacherList ? Pourquoi ne pas utiliser une List<Teacher> ? L'élément PageIndex n'a pas vraiment de rapport, et le nombre de résultats non plus..

      -A quoi sert la classe Language ? Pourquoi ne pas directement utiliser une List<string> comme propriété ?

      -Les propriétés sont censées être en PascalCasing...d'ailleurs, "value" est un mot-clé contextuel C#, j'espère que le compilateur comprend ton code.
      • Partager sur Facebook
      • Partager sur Twitter
        2 juin 2011 à 20:35:42

        Bonjour Aethec, merci de ta réponse rapide.

        Alors, pour la TeacherList, c'était pour rester logique dans la façon de coder, et j'ai vraiment besoin des éléments PageIndex et TotalResults pour plus tard.

        Concernant la classe language, effectivement je sais que ça par contre c'était pas génial mais c'est parce que je n'arrive pas à utiliser le "from ... in ... select ..." avec une List<string> :$. Je ne trouvais pas comment faire :s

        Hmmm PascalCasing, c'est à dire ? Majuscule au début et pour chaque "mot" de la variable ?

        Mais concernant mon problème, as-tu une idée ?
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          2 juin 2011 à 21:05:18

          Je crois que j'ai compris...
          from language in xmlDoc.Descendants( "otherlanguages" )
          select new Language()
          {
              value = language.Element( "language" ).Element( "value" ).Value
          }
          


          Voici ton XML :
          <otherlanguages>
            <label>Autres langues parlées (et Niveau) :</label>
            <language>
              <label>Espagnol</label>
              <level>C2 : Avancé</level>
            </language>
            <language>
              <label>Anglais</label>
              <level>C2 : Avancé</level>
            </language>
          </otherlanguages>
          

          Il n'existe pas d'élément "value" dans les éléments "language".
          En plus, je doute que ton code fasse ce que tu souhaites faire (là ça récupére uniquement le premier langage grâce à la méthode Element...)

          EDIT : De plus, tu ne gères pas le cas où teacher.specialization n'existe pas ^^


          PS : Le PascalCasing, par opposition au camelCasing, consiste à MettreUneMajusculeATousLesMots (alors que le camelCasing consiste à commencerParUneMinuscule).

          PPS : Je te conseille d'enlever la partie avec l'APIKEY de ton code :-°
          • Partager sur Facebook
          • Partager sur Twitter
            2 juin 2011 à 21:59:24

            Effectivement je ne gère pas encore les cas où les champs sont optionnels et donc peuvent être absents mais j'aimerai déjà que ce cas particulier fonctionne ...
            MAIS ! Effectivement ça venait de ça ... Le champ "specialization" n'est pas présent partout ! Et c'est ça qui rendait ma liste "vide" ...

            Merci beaucoup de tes réponses rapides et claires ! Bonne soirée à toi !

            PS : merci de la précision, je vais changer ça
            PPS : oui effectivement, je pensais l'avoir fait mais j'ai du merder quelque part lors du post, dans tous les cas c'est un simple exercice d'école ce n'est pas très grave, l'APIKEY ne sert à rien d'autre :p
            • Partager sur Facebook
            • Partager sur Twitter

            Parsing XML, XDocument et initialisation

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown