6

jsoncppを使用してjsonのセットを解析しようとしています。jsonは、djangoオブジェクトのsimplejsonを使用してWebページから生成されています。libcurlを使用して特定のURLから取得します。ルートで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
   }
]

したがって、データを正しく取得していて、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の出力です。

    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

そのすべてから、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.

あなたが与えることができるどんな助けにも感謝します。

乾杯

マーク

4

2 に答える 2

8

ですから、もう一度、何が起こっているのか理解できない場合でした。

私のjson構造はDjangoモデルからのものだったので、実際にはjsonの配列でした(ここで用語が間違っていることはわかっています。事前に謝罪します)。これは、次のコードから見つけることができます。

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

次の出力で

type: 6

jsoncppでは、これはjsonの配列を意味します。これは、開始角括弧と終了角括弧のStyledoutputからも推測できます。また、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).
   };

一度にDjangoモデルから出力されるデータは1行しかないため、これを判断するのは困難でした。今理解しているように、最初に配列の初期位置を選択する必要があるときに、objectValue型のjson構造体に対して操作を実行しようとしていました。

したがって、実際にURLを取得するには、次のようなことを行う必要があります。

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

これをここに置いて、他の誰かがこれに遭遇した場合、少なくとも何が悪いのかを見つける方法があるようにします。

乾杯

マーク

于 2010-12-15T00:55:45.263 に答える
1

ごめん、

だが

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

あるべきではない

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

曲はフィールドにネストされているため、曲を取得するには、次のようにアクセスする必要があります。

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

いいえ?

于 2010-12-14T12:03:44.417 に答える