2010-12-14 147 views
5

我试图使用jsoncpp来解析一组json。 json是从django对象的simplejson网页生成的。我使用libcurl从特定的URL中获取它。当我在根上使用toStyledString()函数时,我会打印出来。使用jsoncpp从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 
    } 
] 

所以它似乎是我得到的数据权利和它的Json :: Value类。

问题是我无法从json结构中获取特定的节点。这是我使用的代码。

#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; 
} 

,因为另一个问题,我不使用实际libjson.so共享库,我只是拉中的文件,并与我的源代码编译他们(我猜这是不好的,但问题是不是这个问题的重点)。以下是我的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 

这是make的输出。

[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 

,并从所有的,我得到下面的输出,当我执行鸟

*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 
    } 
] 

我不,如果我注释掉该行

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

进出口完全开放,以获得问题我在这里做错了事实。但我只是不知道它是什么。那么是什么导致了错误:

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

感谢您的任何帮助,你可以给。

干杯

马克

回答

7

所以再一次,这是一个不理解发生了什么事情。

因为我的json结构来自Django模型,它实际上是json数组(我知道我会在这里弄错术语,并且我提前道歉)。这可以从下面的代码中找到:

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

具有以下输出

type: 6 
在jsoncpp

,这意味着JSON的阵列。这也可以从开始和结束的方括号中的Styledoutput中得到。此外,从该枚举中value.h开始上线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). 
    }; 

这很难说,因为我只用了数据出来我的Django模型的时候一行。据我现在的理解,当我真的需要首先选择初始数组位置时,我试图为objectValue类型的json结构执行操作。

所以要真正得到我需要做的这样的网址。

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

这将让你

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

从以下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 
    } 
] 

林把这个位置,这样,如果任何人遇到这样他们将至少有发现的一些方法出了什么问题。

干杯

马克

1

对不起,

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

不应该

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

歌曲嵌套到字段,因此得到的歌曲你应该这样访问它:

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

不是?

+0

肯定这就是正确的。但我仍然得到同样的错误。我会在问题中更新代码。好的地方tho! – 2010-12-14 12:46:38

+1

问题是由服务器返回的JSON包装到数组中:[{“fields”:....}],这就是为什么断言失败... – 2010-12-14 12:57:34