简体   繁体   English

使用jsoncpp从JSON中获取节点的问题

[英]Problems with getting a node out of JSON with jsoncpp

Im trying to use jsoncpp to parse a set of json. 我试图使用jsoncpp来解析一组json。 The json has been generated from a webpage with simplejson from a django object. json是使用来自django对象的simplejson从网页生成的。 I get it from a particular URL using libcurl. 我使用libcurl从特定的URL获取它。 WHen I use the toStyledString() function on the root I get this printed out. 当我在根上使用toStyledString()函数时,我将其打印出来。

[
   {
      "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
   }
]

So it seems like I am getting the data right and its in a Json::Value class. 所以看起来我正在获取数据并将其放在Json :: Value类中。

The problem is that im unable to get a particular node out of the json structure. 问题是我无法从json结构中获取特定节点。 This is the code im using. 这是我正在使用的代码。

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

because of another issue I'm not using the actual libjson.so shared library, im just pulling in the files and compiling them in with my source (I'm guessing this is bad, but that problem is not the point of this question). 因为另一个问题我没有使用实际的libjson.so共享库,我只是拉入文件并用我的源码编译它们(我猜这很糟糕,但问题不是这个问题的重点) 。 Below is how my src folder is structured. 下面是我的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

and this is the output of make. 这是make的输出。

    munderwo@bertha:/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

and from all of that I get the following output when I execute Bird 从我执行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
   }
]

I dont get the problem if I comment out this line 如果我注释掉这一行,我就不会遇到问题

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

Im totally open to the fact that im doing something wrong here. 我完全接受这样一个事实:我在这里做错了。 But I just dont know what it is. 但我只是不知道它是什么。 So what is causing the error: 那么是什么导致了错误:

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

thanks for any help you can give. 谢谢你提供的所有帮助。

Cheers 干杯

Mark 标记

So once again it was a case of not understanding what was going on. 所以再一次是不理解发生了什么的情况。

Because my json structure was from a Django model it was actually and array of json (I know im going to get the terminology wrong here, and I apologize in advance). 因为我的json结构来自Django模型,它实际上是json的数组(我知道我会在这里得到错误的术语,我提前道歉)。 This could be found from the following code: 这可以从以下代码中找到:

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

with the following output 具有以下输出

type: 6

in jsoncpp, this means an array of json. 在jsoncpp中,这意味着一个json数组。 This can also be infered from the Styledoutput from the starting and ending square brackets. 这也可以从开始和结束方括号的Styledoutput中获取。 Also from this enum in value.h starting on line 23 也可以从第23行开始的value.h中的这个枚举

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).
   };

This was harder to tell because I only had one row of data coming out of my Django Model at the time. 这很难分辨,因为我当时只有一行数据来自我的Django模型。 As I understand now, I was trying to do an operation for an objectValue type json structure, when I really needed to select the initial array position first. 据我所知,我正在尝试对objectValue类型的json结构进行操作,当我真的需要先选择初始数组位置时。

So to actually get at the url I need to do something like this. 所以要真正得到网址我需要做这样的事情。

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

which will get you 这会得到你

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

from the following json 来自以下的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 putting this here so that if anyone else comes across this they will at least have some way of finding out what is wrong. 我把它放在这里,以便如果有人遇到这个,他们至少会找到一些方法来找出问题所在。

Cheers 干杯

Mark 标记

Sorry, 抱歉,

But

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

Shouldn't be 不应该

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

songs is nested into fields, so to get the songs you should access it like this: 歌曲嵌入到字段中,因此要获取歌曲,您应该像这样访问它:

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

No? 没有?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM