2017-09-22 3 views
0

J'utilise gSOAP (en C) pour une application cliente qui appelle un service Web Java. J'utilise la fonction json_call(). J'ai une structure de requête remplie avec les données d'entrée JSON et j'obtiens une structure de réponse remplie avec les données de sortie JSON du service Java. Les deux JSON ont la même structure en général, mais peuvent avoir plus, moins ou changé d'éléments.gSOAP: Comment comparer deux structures de valeur (avec un contenu JSON) en C?

Ma tâche est maintenant de savoir dans quels éléments la réponse est différente de la requête. Le principal élément est un grand tableau avec beaucoup de membres, comme:

{ 
    "objects": [ 
    { 
     "@id": "OBJ00001", 
     "name": "value", 
     ... 
    }, 
    { 
     "@id": "OBJ00002", 
     "number": 123, 
     ... 
    }, 
    ... 
    ] 
} 

je peux identifier tout objet du même genre avec le champ @id.

ESt simple à itérer le tableau objects avec quelque chose comme:

for(i = 0; i < has_size(value_at(response, "objects")); i++) 

Mais I'missing alors une fonction, qui permet de comparer les membres (« objets ») avec le même @id à la demande et la réponse. Quelque chose comme « findMemberWithSameField », puis « égale » (tous deux n'existe pas!):

struct member *currentMemberInResponse = NULL; 
struct member *memberWithSameField  = NULL; 

for(i = 0; i < has_size(value_at(response, "objects")); i++) 
{ 
    /* get the current member out of the response array */ 
    currentMemberInResponse = nth_value(value_at(response, "objects"), i); 

    /* Find member/object with same @id in request */ 
    memberWithSameField = findMemberWithSameField(value_at(request, "objects"), currentMemberInResponse , "@id")); 

    /* equal is true if all fields are the same */ 
    if(equal(currentMemberInResponse, memberWithSameField)) 
    { 
     /* Do nothing, because nothing changed */ 
    } 
    else 
    { 
     /* Do something */ 
    } 
} 

Toute idée sur cette tâche? Sinon, je dois écrire mes propres "findMemberWithSameField" et "euqal".

Amitiés Daniel

+0

ici jetez un oeil à https://github.com/DaveGamble/cJSON il a le support de patch jSON –

Répondre

0

L'API JSON C++ définit operator== pour comparer deux objets récursive. La dernière version 2.8.55 travaux (je l'ai testé) pour comparer deux objets JSON, où operator== appelle la fonction suivante:

bool json_eqv(const value& x, const value& y) 
{ 
    ... 
    switch (x.__type) 
    { 
    ... 
    case SOAP_TYPE__struct: 
     if (x.size() != y.size()) 
     return false; 
     else 
     { 
     const _struct& s = x; 
     const _struct& t = y; 
     for (_struct::iterator i = s.begin(); i != s.end(); ++i) 
     { 
      _struct::iterator j; 
      for (j = t.begin(); j != t.end(); ++j) 
      if (!strcmp(i.name(), j.name())) 
       break; 
      if (j == t.end() || *i != *j) 
      return false; 
     } 
     return true; 
     } 

Cela peut être réécrite à C avec quelque chose comme:

int json_eqv(const value *x, const value *y) 
{ 
    if (x->__type != y->__type && 
     (x->__type != SOAP_TYPE__i4 || y->__type != SOAP_TYPE__int) && 
     (x->__type != SOAP_TYPE__int || y->__type != SOAP_TYPE__i4)) 
    return false; 
    switch (x->__type) 
    { 
    case SOAP_TYPE__boolean: 
    case SOAP_TYPE__i4: 
    case SOAP_TYPE__int: 
     return int_of(x) == int_of(y); 
    case SOAP_TYPE__double: 
     return double_of(x) == double_of(y); 
    case SOAP_TYPE__string: 
    case SOAP_TYPE__dateTime_DOTiso8601: 
     return !strcmp(string_of(x), string_of(y)); 
    case SOAP_TYPE__struct: 
     if (has_size(x) != has_size(y)) 
     return 0; 
     else 
     { 
     size_t i, j; 
     for (i = 0; i < has_size(x); ++i) 
     { 
      for (j = 0; j < has_size(y); ++j) 
      if (!strcmp(nth_member(x, i), nth_member(y, j)) 
       break; 
      if (j == has_size(y) || !json_eqv(nth_value(x, i), nth_value(y, j)) 
      return 0; 
     } 
     return 1; 
     } 
    case SOAP_TYPE__array: 
     if (has_size(x) != has_size(y)) 
     return 0; 
     else 
     { 
     int i; 
     for (i = 0 ; i < has_size(x); ++i) 
      if (!json_eqv(nth_nth(x, i), nth_nth(y, i)) 
      return 0; 
     return 1; 
     } 
    default: 
     return 0; 
    } 
}