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

C# Discussion :

Parser/ traiter du JSON


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut Parser/ traiter du JSON
    Bonjour,

    Je voudrais parser le contenu de la requête suivante afin de récupérer le nom des sociétés données ("name": "Google Inc.", etc), le "ticker symbol" ("symbol":"GOOG") et la Bourse qui cote l'entreprise ("exchDisp":"NASDAQ").

    Le résultat de la requête (de façon lisible ...) est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    YAHOO.Finance.SymbolSuggest.ssCallback({"ResultSet":
    {"Query":"google","Result":[{"symbol":"GOOG","name": "Google Inc.","exch": "NMS","type": "S","exchDisp":"NASDAQ","typeDisp":"Equity"},
    {"symbol":"GOOG.MX","name": "Google, Inc.","exch": "MEX","type": "S","exchDisp":"Mexico","typeDisp":"Equity"}, etc
    Seulement c'est a priori du JSON (c'est ce qu'on m'a dit), et j'avais voulu le parser à la main en fonction des accolades et des virgules. Ça marche nickel. Le problème ? Dès qu'une entreprise a une virgule dans son nom, ça ne marche plus du tout !

    J'ai donc fait des recherches, suis tombé sur la même problématique en JAVA (qui utilise JSONObject et JSONArray) sauf que je ne sais pas comment parser du JSON avec C#.

    Puis je suis tombé sur un topic de ce forum et une personne parlait de désérialiser le JSON via DataContractJsonSerializer. Est-ce que ça marcherait pour une requête comprenant différentes "entreprises" ? (J'espère être clair )

    Quelqu'un aurait une autre piste svp ?

    Merci par avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Ub1quity Voir le message
    Puis je suis tombé sur un topic de ce forum et une personne parlait de désérialiser le JSON via DataContractJsonSerializer. Est-ce que ça marcherait pour une requête comprenant différentes "entreprises" ? (J'espère être clair )
    T'as pas cherché bien loin. Dans le lien MSDN que tu as fourni ce dernier t'offre un autre lien vers un exemple de code te permettant de faire cela. Regardes ici.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Bonsoir,

    Merci pour ta réponse, mais ce n'est pas l'implémentation de la désérialisation pour un "objet" qui me pose problème actuellement (a priori c'est la même chose qu'avec un flux d'octets, après je ne suis pas un expert). C'est bien la structure JSON en elle-même (C'est la première fois que j'y suis confronté).

    Car dans la requête il y a différentes entreprises. C'est là où je ne sais pas quoi faire ...

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    Tu peux aussi regarder du coté de JSON.NET http://json.codeplex.com/

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Ub1quity Voir le message
    Car dans la requête il y a différentes entreprises. C'est là où je ne sais pas quoi faire ...
    Tu bloques uniquement au niveau de comment tu vas définir la structure de ta ou tes classes pour correspondre parfaitement au contenu JSON que tu as.
    Avec DataContractJsonSerializer tu définis d'abords ta structure comme suit :
    Code C# : 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
     
    namespace Test {
      [DataContract]
      public class QueryResult {
        [DataMember]
        public ResultSet ResultSet { get; set; }
      }
     
      [DataContract]
      public class ResultSet {
        [DataMember]
        public string Query { get; set; }
        [DataMember(Name="Result")]
        public List<Company> Companies { get; set; }
      }
     
      [DataContract]
      public class Company {
        [DataMember(Name="symbol")]
        public string Symbol    { get; set; }
        [DataMember(Name = "name")]
        public string Name      { get; set; }
        [DataMember(Name = "exch")]
        public string Exch      { get; set; }
        [DataMember(Name = "type")]
        public string Type      { get; set; }
        [DataMember(Name = "exchDisp")]
        public string ExchDisp  { get; set; }
        [DataMember(Name = "typeDisp")]
        public string TypeDisp  { get; set; } 
      }
    }
    et pour désérailiser tu fais comme suit :
    Code C# : 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
     
    static void deserializeWithDataContractJsonSerializer(string value) {
          try {
            Console.WriteLine("Désérialisation avec DataContractJsonSerializer");
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(QueryResult));
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(value));
            QueryResult result = (QueryResult)serializer.ReadObject(ms);
            if (result == null) throw new Exception("La désérialisation n'a pas marché");
     
            foreach (Company company in result.ResultSet.Companies) {
              Console.WriteLine("symbol: {0} - name: {1} - exch: {2} - type: {3} - exhcDisp: {4} - typeDisp: {5}", company.Symbol, company.Name, company.Exch, company.Type, company.ExchDisp, company.TypeDisp);
            }
          } catch (Exception ex) {
            Console.WriteLine(ex.Message);
          }
          Console.WriteLine("================================");
        }

    Avec Json.net (le lien que t'as filé nico-pyright(c)) c'est plus simple en effet grâce à Linq To Json tu fais comme ça :
    Code C# : 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
     
    static void deserailizeWithJsonDotNet(string value) {
          try {
            Console.WriteLine("Désérialisation avec Json.Net");
            var companies = from company in JObject.Parse(value)["ResultSet"]["Result"].Children()
                            select new
                            {
                              Symbol = company["symbol"],
                              Name = company["name"],
                              Exch = company["exch"],
                              Type = company["type"],
                              ExchDisp = company["exchDisp"],
                              TypeDisp = company["typeDisp"]
                            };
     
            foreach (var company in companies) {
              Console.WriteLine("symbol: {0} - name: {1} - exch: {2} - type: {3} - exhcDisp: {4} - typeDisp: {5}", company.Symbol, company.Name, company.Exch, company.Type, company.ExchDisp, company.TypeDisp);
            }
          } catch (Exception ex) {
            Console.WriteLine(ex.Message);
          }
          Console.WriteLine("================================");
        }

    Ci-dessous le code de test complet :
    Code C# : 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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    namespace Test {
      [DataContract]
      public class QueryResult {
        [DataMember]
        public ResultSet ResultSet { get; set; }
      }
     
      [DataContract]
      public class ResultSet {
        [DataMember]
        public string Query { get; set; }
        [DataMember(Name="Result")]
        public List<Company> Companies { get; set; }
      }
     
      [DataContract]
      public class Company {
        [DataMember(Name="symbol")]
        public string Symbol    { get; set; }
        [DataMember(Name = "name")]
        public string Name      { get; set; }
        [DataMember(Name = "exch")]
        public string Exch      { get; set; }
        [DataMember(Name = "type")]
        public string Type      { get; set; }
        [DataMember(Name = "exchDisp")]
        public string ExchDisp  { get; set; }
        [DataMember(Name = "typeDisp")]
        public string TypeDisp  { get; set; } 
      }
     
      class Program {
        static void Main(string[] args) {
          string value = @"{
                              ""ResultSet"": 
                              {
                                  ""Query"":""google"",
                                  ""Result"": 
                                  [
                                      {   
                                          ""symbol"": ""GOOG"",
                                          ""name"": ""Google Inc."",
                                          ""exch"": ""NMS"",
                                          ""type"": ""S"",
                                          ""exchDisp"": ""NASDAQ"",
                                          ""typeDisp"": ""Equity""
                                      },
                                      {
                                          ""symbol"": ""GOOG.MX"",
                                          ""name"": ""Google, Inc."",
                                          ""exch"": ""MEX"",
                                          ""type"": ""S"",
                                          ""exchDisp"": ""Mexico"",
                                          ""typeDisp"": ""Equity""
                                      }
                                  ]
                              }
                          }";
     
          deserializeWithDataContractJsonSerializer(value);
          deserailizeWithJsonDotNet(value);
          Console.ReadKey();
        }
     
        static void deserailizeWithJsonDotNet(string value) {
          try {
            Console.WriteLine("Désérialisation avec Json.Net");
            var companies = from company in JObject.Parse(value)["ResultSet"]["Result"].Children()
                            select new
                            {
                              Symbol = company["symbol"],
                              Name = company["name"],
                              Exch = company["exch"],
                              Type = company["type"],
                              ExchDisp = company["exchDisp"],
                              TypeDisp = company["typeDisp"]
                            };
     
            foreach (var company in companies) {
              Console.WriteLine("symbol: {0} - name: {1} - exch: {2} - type: {3} - exhcDisp: {4} - typeDisp: {5}", company.Symbol, company.Name, company.Exch, company.Type, company.ExchDisp, company.TypeDisp);
            }
          } catch (Exception ex) {
            Console.WriteLine(ex.Message);
          }
          Console.WriteLine("================================");
        }
     
        static void deserializeWithDataContractJsonSerializer(string value) {
          try {
            Console.WriteLine("Désérialisation avec DataContractJsonSerializer");
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(QueryResult));
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(value));
            QueryResult result = (QueryResult)serializer.ReadObject(ms);
            if (result == null) throw new Exception("La désérialisation n'a pas marché");
     
            foreach (Company company in result.ResultSet.Companies) {
              Console.WriteLine("symbol: {0} - name: {1} - exch: {2} - type: {3} - exhcDisp: {4} - typeDisp: {5}", company.Symbol, company.Name, company.Exch, company.Type, company.ExchDisp, company.TypeDisp);
            }
          } catch (Exception ex) {
            Console.WriteLine(ex.Message);
          }
          Console.WriteLine("================================");
        }
      }
    }

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Wah ...

    Que dire à part "Merci !" ? Merci à tous les deux.

    Effectivement le LINQ To JSON a l'air plus "accessible". Il ne me reste plus qu'à réussir à l'installer, et à supprimer le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    YAHOO.Finance.SymbolSuggest.ssCallback
    de Yahoo ...
    Et à comprendre comment ça marche !

    Par contre, je ne comprends pas à quoi sert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [DataMember(Name="symbol")]
    dans la classe Company.
    Est-ce pour "signaler" que le "nœud" JSON (si on fait une analogie avec XML) correspond à la variable Company.Symbol ?

    Encore merci.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Bon ... ça ne veut pas compiler ; ça ne connait pas tout ce qui est "DataContract" et compagnie.

    J'ai les "using" suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    using Newtonsoft.Json;
    using System.Runtime.Serialization;
    Et j'ai copié collé le bin de .Net 4.0 dans le dossier de mon projet et ajouté une référence vers le .dll.

    L'autocomplétion ne me permet pas de faire System.Runtime.Serialization.Json, sachant que j'utilise .Net 4.0.

    Comment faire ?

    Merci par avance.

    __
    EDIT :
    Sachant que je ne peux pas non plus faire appel à "System.ServiceModel.Web" ...

  8. #8
    Invité
    Invité(e)
    Par défaut
    Il faut d'abords ajouter les références suivantes :
    • L'assembly System.ServiceModel.Web.dll si tu es en .Net 3.5 ou System.Runtime.Serailization.dll si tu es en .Net 4.0
    • Tu télécharges json.codeplex.com et tu ajoute la références à l'assembly Newtonsoft.Json.dll


    Tu ajoutes les namespaces requis. VS pourra t'aider pour ça.
    Pour les propriétés où j'utilise l'attribut DataMember avec la propriété Name renseignée cela est dû au fait que le nom ne respectait pas la case définit dans la donnée JSON et est tout simplement différent.

    Si tu utilises Json.Net alors tu n'as pas besoin des classes QueryResult, ResutSet et Company vu que j'utilises les types anonymes.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Merci, en fait c'est la même démarche que pour le : ajouter la référence puis mettre le "using". Je n'y ai même pas pensé ...

    Hmmm j'ignore ce que sont les types anonymes. A la réflexion, tu entends "inférence de type" pour les "types anonymes" ? Je dis ça à cause des "var" dans le code.

    Pourquoi Json.Net rend inutile les trois classes sur que utilises ?
    Ce qui veut dire que la méthode "static void deserailizeWithJsonDotNet(string value)" se suffit à elle-même ?

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Ub1quity Voir le message
    Hmmm j'ignore ce que sont les types anonymes. A la réflexion, tu entends "inférence de type" pour les "types anonymes" ? Je dis ça à cause des "var" dans le code.
    Pour les types anonymes regarde ici.

    Citation Envoyé par Ub1quity Voir le message
    Pourquoi Json.Net rend inutile les trois classes sur que utilises ?
    Elles sont inutiles parce que avec Json.Net je ne les utilise pas mais j'utilise plutôt les types anonymes. La seule classe qui pourrait être utile dans le cas de Json.Net est la classe Company et à utiliser comme suit :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    List<Company> companies = from company in JObject.Parse(value)["ResultSet"]["Result"].Children()
                            select new Company
                            {
                              Symbol = company["symbol"],
                              Name = company["name"],
                              Exch = company["exch"],
                              Type = company["type"],
                              ExchDisp = company["exchDisp"],
                              TypeDisp = company["typeDisp"]
                            };

    Citation Envoyé par Ub1quity Voir le message
    Ce qui veut dire que la méthode "static void deserailizeWithJsonDotNet(string value)" se suffit à elle-même ?
    Oui.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Merci, je connais les type anonymes alors

    Si tu fais
    Citation Envoyé par h2s84 Voir le message
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    List<Company> companies = from company in JObject.Parse(value) ["ResultSet"]["Result"].Children()/* var est remplacé par List<Company>*/
                            select new Company
                            {
                              Symbol = company["symbol"],
                              Name = company["name"],
                              Exch = company["exch"],
                              Type = company["type"],
                              ExchDisp = company["exchDisp"],
                              TypeDisp = company["typeDisp"]
                            };
    On est d'accord que c'est dans "static void deserailizeWithJsonDotNet(string value)" et qu'il faut quand même garder la classe Company (ci-après)?
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [DataContract]
      public class Company {
        [DataMember(Name="symbol")]
        public string Symbol    { get; set; }
        [DataMember(Name = "name")]
        public string Name      { get; set; }
        [DataMember(Name = "exch")]
        public string Exch      { get; set; }
        [DataMember(Name = "type")]
        public string Type      { get; set; }
        [DataMember(Name = "exchDisp")]
        public string ExchDisp  { get; set; }
        [DataMember(Name = "typeDisp")]
        public string TypeDisp  { get; set; } 
      }

    Désolé, questions basiques mais c'est pour être sûr d'avoir bien compris. Je te remercie pour ta patience au passage

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Ub1quity Voir le message
    On est d'accord que c'est dans "static void deserailizeWithJsonDotNet(string value)" et qu'il faut quand même garder la classe Company (ci-après)?
    Oui c'est bien ça.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Hmm ... J'ai fait les ajouts des deux .dll (je suis en .Net 4.0 mais dans le doute ...) et pourtant JObjet et MemoryStream ne sont toujours pas reconnus.

    Je me retrouve avec
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using Newtonsoft.Json;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.ServiceModel.Web;

    Encore un using manquant ?

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Ub1quity Voir le message
    Encore un using manquant ?
    Survole les classes qui ne sont pas reconnues et VS fera apparaître un petit rectangle. Tu cliques sur le rectangle et il te proposera d'ajouter le using manquant si tu es sûr que les assemblys indispensables sont déjà référencés.

    Sinon pour ton cas actuel. Il s'agit de :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    using System.IO;
    using Newtonsoft.Json.Linq;

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Le programme compile et s'exécute normalement

    Merci h2s84 ! Je ne connaissais pas le coup du petit rectangle pour VS. Je m'arrêtais à la phrase du genre "une dll est-elle manquante ?"

    Cette fois le problème est vraiment résolu

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

Discussions similaires

  1. Parser un fichier Json
    Par laurent30s dans le forum Contribuez
    Réponses: 2
    Dernier message: 14/05/2019, 14h21
  2. Parser deux tableaux JSON imbriqués
    Par Arwa89 dans le forum Android
    Réponses: 2
    Dernier message: 21/04/2013, 00h37
  3. Parser LDAP vers Json ?
    Par guilopouloos dans le forum Servlets/JSP
    Réponses: 0
    Dernier message: 28/07/2011, 09h52
  4. Parser un flux JSON
    Par Cool_Boy dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 07/06/2011, 11h15
  5. Parser un fichier JSON en Java
    Par zinga dans le forum Android
    Réponses: 5
    Dernier message: 09/02/2011, 17h45

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