2010-12-14 23 views
5

Próbuję użyć jsoncpp do parsowania zestawu json. Json został wygenerowany na stronie internetowej z simplejson z obiektu django. Dostaję go z konkretnego adresu URL przy użyciu libcurl. Kiedy używam funkcji toStyledString() w katalogu głównym, otrzymuję to wydruk.Problemy z uzyskaniem węzła z JSON z jsoncpp

[ 
    { 
     "fields" : { 
     "desc" : "Carol King test", 
     "format" : "1", 
     "genre" : "Pop", 
     "mount" : "CarolKing", 
     "name" : "Carol King", 
     "protocol" : "0", 
     "songs" : [ 27, 28, 29, 30, 31, 32, 33, 34 ], 
     "url" : "http://192.168.0.5:8000/CarolKing" 
     }, 
     "model" : "music.playlist", 
     "pk" : 2 
    } 
] 

Wygląda na to, że uzyskuję prawidłowe dane w klasie Json :: Value.

Problem polega na tym, że nie można uzyskać określonego węzła ze struktury json. To jest kod, którego używam.

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sstream> 
#include <curl/curl.h> 
#include <string> 
#include "Parameter.h" 
#include "lib_json/json.h" 

using namespace std; 

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) 
{ 
    cout << "-->write_data " << endl; 
    string buf = string(static_cast<char *>(ptr), size *nmemb); 
    stringstream * response = static_cast<stringstream *>(stream); 
    response->write(buf.c_str(), (streamsize)buf.size()); 
    return size * nmemb; 

} 


int main(int sys_argc, char ** sys_argv) { 
    CURL *curl; 
    CURLcode res; 
    stringstream response; 
    string error; 

    char ** argv = sys_argv; 


    string file = argv[1]; 
    Parameter *parms = new Parameter(file); 
    parms->ReadParameters(); 

    cout << "URL: " << parms->GetParameter("URL"); 


    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init(); 
    if(curl) 
    { 
     curl_easy_setopt(curl, CURLOPT_URL, parms->GetParameter("URL").c_str()); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); 
     res = curl_easy_perform(curl); 

     cout << "Playlists-JSON: " << response.str() << endl; 
     curl_easy_cleanup(curl); 
    } 

    Json::Value root; 
    Json::Reader reader; 

    bool parsingSuccessful = reader.parse(response.str(), root); 

    if(!parsingSuccessful) 
    { 
     cout << "Failed to parse configuration. " << reader.getFormatedErrorMessages(); 
     return 16; 
    } 

    cout << "Pretty-Print: " << root.toStyledString() << endl; 
    const Json::Value fields = root["fields"]["songs"]; 


    return 0; 
} 

powodu innego problemu nie używam Rzeczywisty libjson.so biblioteki współdzielonej, im po prostu ciągnąc w plikach i zestawiania ich w moim źródła (zgaduję to jest złe, ale problemem jest to, że nie chodzi o to pytanie). Poniżej znajduje się struktura mojego folderu src.

.: 
bird Bird.cpp fopen.cpp fopen.h lib_json Parameter.cpp Parameter.h 

./lib_json: 
autolink.h features.h json_batchallocator.h json_internalarray.inl json_reader.cpp json_valueiterator.inl reader.h value.h 
config.h forwards.h json.h     json_internalmap.inl json_value.cpp json_writer.cpp   sconscript writer.h 

i jest to wyjście producenta.

[email protected]:/local/Documents/inthebackground/Box/Bird/bird/Debug$ make 
Building file: ../src/lib_json/json_reader.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/lib_json/json_reader.d" -MT"src/lib_json/json_reader.d" -o"src/lib_json/json_reader.o" "../src/lib_json/json_reader.cpp" 
Finished building: ../src/lib_json/json_reader.cpp 

Building file: ../src/lib_json/json_value.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/lib_json/json_value.d" -MT"src/lib_json/json_value.d" -o"src/lib_json/json_value.o" "../src/lib_json/json_value.cpp" 
Finished building: ../src/lib_json/json_value.cpp 

Building file: ../src/lib_json/json_writer.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/lib_json/json_writer.d" -MT"src/lib_json/json_writer.d" -o"src/lib_json/json_writer.o" "../src/lib_json/json_writer.cpp" 
Finished building: ../src/lib_json/json_writer.cpp 

Building file: ../src/Bird.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Bird.d" -MT"src/Bird.d" -o"src/Bird.o" "../src/Bird.cpp" 
Finished building: ../src/Bird.cpp 

Building file: ../src/Parameter.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Parameter.d" -MT"src/Parameter.d" -o"src/Parameter.o" "../src/Parameter.cpp" 
../src/Parameter.cpp: In member function ‘int Parameter::ReadParameters()’: 
../src/Parameter.cpp:47: warning: comparison between signed and unsigned integer expressions 
Finished building: ../src/Parameter.cpp 

Building file: ../src/fopen.cpp 
Invoking: GCC C++ Compiler 
g++ -I"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/include" -I"/local/Documents/inthebackground/Box/Bird/bird/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/fopen.d" -MT"src/fopen.d" -o"src/fopen.o" "../src/fopen.cpp" 
Finished building: ../src/fopen.cpp 

Building target: Bird 
Invoking: GCC C++ Linker 
g++ -L"/local/Documents/inthebackground/Box/Bird/bird/Libraries/i386/lib" -o"Bird" ./src/lib_json/json_reader.o ./src/lib_json/json_value.o ./src/lib_json/json_writer.o ./src/Bird.o ./src/Parameter.o ./src/fopen.o -lcurl 
Finished building target: Bird 

i od wszystkich, że pojawia się następujący wyjście kiedy wykonać ptak

*Bird: ../src/lib_json/json_value.cpp:1025: Json::Value& Json::Value::resolveReference(const char*, bool): Assertion `type_ == nullValue || type_ == objectValue' failed.* 
URL: 127.0.0.1:8000/playlist-->write_data 
Playlists-JSON: [{"pk": 2, "model": "music.playlist", "fields": {"protocol": "0", "name": "Carol King", "format": "1", "url": "http://192.168.0.5:8000/CarolKing", "mount": "CarolKing", "genre": "Pop", "songs": [27, 28, 29, 30, 31, 32, 33, 34], "desc": "Carol King test"}}] 
Pretty-Print: [ 
    { 
     "fields" : { 
     "desc" : "Carol King test", 
     "format" : "1", 
     "genre" : "Pop", 
     "mount" : "CarolKing", 
     "name" : "Carol King", 
     "protocol" : "0", 
     "songs" : [ 27, 28, 29, 30, 31, 32, 33, 34 ], 
     "url" : "http://192.168.0.5:8000/CarolKing" 
     }, 
     "model" : "music.playlist", 
     "pk" : 2 
    } 
] 

dont dostać problem gdybym skomentować tę linię

const Json::Value fields = root["songs"]; 

Im całkowicie otwarte fakt, że robię coś złego tutaj. Ale po prostu nie wiem, co to jest. Więc co jest przyczyną błędu:

Bird: ../src/lib_json/json_value.cpp:1025: Json::Value& Json::Value::resolveReference(const char*, bool): Assertion `type_ == nullValue || type_ == objectValue' failed. 

dziękuję za pomoc.

Cheers

Mark

Odpowiedz

7

Po raz kolejny okazało się, że nie rozumiemy, co się dzieje.

Ponieważ moja struktura JSON była z modelu Django, faktycznie była to tablica jsonów (wiem, że źle rozumiem terminologię i z góry przepraszam).Może to znaleźć w poniższej kodu:

cout << "type: " << root.type() << endl; 

z następującym wyjściu

type: 6 

w jsoncpp, to znaczy szereg JSON. Może to być również wywołane przez Styledoutput z początkowych i końcowych nawiasów kwadratowych. Również z tego wyliczenia w value.h począwszy od linii 23

enum ValueType 
    { 
     nullValue = 0, ///< 'null' value 
     intValue,  ///< signed integer value 
     uintValue,  ///< unsigned integer value 
     realValue,  ///< double value 
     stringValue, ///< UTF-8 string value 
     booleanValue, ///< bool value 
     arrayValue, ///< array value (ordered list) 
     objectValue ///< object value (collection of name/value pairs). 
    }; 

Było trudniej powiedzieć, bo miałem tylko jeden wiersz danych pochodzących z moim Django modelu w czasie. Jak rozumiem teraz, próbowałem wykonać operację dla struktury json typu objectalue, kiedy naprawdę musiałem najpierw wybrać początkową pozycję tablicy.

Aby uzyskać dostęp do adresu URL, muszę zrobić coś takiego.

for(int i = 0; i < root.size(); i++) 
    { 
     cout << root[i]["fields"]["url"].asString() << endl; 
    } 

który będzie Ci

http://192.168.0.5:8000/CarolKing 
http://192.168.0.5:8000/CarolKing2 

z poniższego json

[ 
    { 
     "fields" : { 
     "desc" : "Carol King test", 
     "format" : "1", 
     "genre" : "Pop", 
     "mount" : "CarolKing", 
     "name" : "Carol King", 
     "protocol" : "0", 
     "songs" : [ 27, 28, 29, 30, 31, 32, 33, 34 ], 
     "url" : "http://192.168.0.5:8000/CarolKing" 
     }, 
     "model" : "music.playlist", 
     "pk" : 2 
    }, 
    { 
     "fields" : { 
     "desc" : "Second carol King", 
     "format" : "1", 
     "genre" : "Pop", 
     "mount" : "CarolKing2", 
     "name" : "Carol King 2", 
     "protocol" : "0", 
     "songs" : [ 26, 27, 28, 29, 30 ], 
     "url" : "http://192.168.0.5:8000/CarolKing2" 
     }, 
     "model" : "music.playlist", 
     "pk" : 35 
    } 
] 

Im oddanie to tutaj tak, że jeśli ktoś napotka to będą przynajmniej mieć jakiś sposób na znalezienie co jest nie tak.

Cheers

Oznacz

1

Niestety,

Ale

const Json::Value fields = root["songs"]; 

nie należy

const Json::Value fields = root["fields"]; 

piosenki jest zagnieżdżony w dziedzinach, tak aby utwory należy uzyskać do niego dostęp w następujący sposób:

const Json::Value songs = root["fields"]["songs"]; 

Nie?

+0

tak ów prawo. Ale wciąż mam ten sam błąd. Zaktualizuję kod w pytaniach. Dobre miejsce! –

+1

Problem polega na tym, że JSON zwrócony przez serwer jest zawijany w tablicę: [{"fields": ....}], dlatego asercja kończy się niepowodzeniem ... –

Powiązane problemy