2011-01-26 41 views
20

jsoncppを使用してJSON文字列をデコードするC++アプリケーションがあります。私は次の関数を作成しましたが、トップレベルのオブジェクトのみを表示します...JsonCppでオブジェクトを反復する

オブジェクトリスト全体をダンプするにはどうすればよいですか?

--Function--

SaveJSON(json_data); 

bool CDriverConfigurator::PrintJSONTree(Json::Value & root, unsigned short depth /* = 0 */) 
{ 
    printf(" {type=[%d], size=%d} ", root.type(), root.size()); 

    if(root.size() > 0) { 
     for(Json::ValueIterator itr = root.begin() ; itr != root.end() ; itr++) { 
      PrintJSONTree(itr.key(), depth+1); 
     } 
     return true; 
    } 

    // Print depth. 
    for(int tab = 0 ; tab < depth; tab++) { 
     printf("-"); 
    } 

    if(root.isString()) { 
     printf(" %s", root.asString().c_str()); 
    } else if(root.isBool()) { 
     printf(" %d", root.asBool()); 
    } else if(root.isInt()) { 
     printf(" %d", root.asInt()); 
    } else if(root.isUInt()) { 
     printf(" %d", root.asUInt()); 
    } else if(root.isDouble()) { 
     printf(" %f", root.asDouble()); 
    } 
    else 
    { 
     printf(" unknown type=[%d]", root.type()); 
    } 


    printf("\n"); 
    return true; 
} 

---入力----

{ 
    "modules":[ 
     { 
     "config":{ 
      "position":[ 
       129, 
       235 
      ] 
     }, 
     "name":"Modbus Task", 
     "value":{ 
      "DeviceID":"This is the name", 
      "Function":"01_READ_COIL_STATUS", 
      "Length":"99", 
      "Scan":"111", 
      "Type":"Serve" 
     } 
     }, 
     { 
     "config":{ 
      "position":[ 
       13, 
       17 
      ] 
     }, 
     "name":"Modbus Connection", 
     "value":{ 
      "Baud":"9600", 
      "timeout":"2.5" 
     } 
     }, 
     { 
     "config":{ 
      "position":[ 
       47, 
       145 
      ] 
     }, 
     "name":"Modbus Device", 
     "value":{ 
      "DeviceID":"55" 
     } 
     }, 
     { 
     "config":{ 
      "position":[ 
       363, 
       512 
      ] 
     }, 
     "name":"Function Something", 
     "value":{ 

     } 
     }, 
     { 
     "config":{ 
      "position":[ 
       404, 
       701 
      ] 
     }, 
     "name":"Function Something", 
     "value":{ 

     } 
     } 
    ], 
    "properties":{ 
     "Blarrg":"", 
     "description":"", 
     "name":"Modbus" 
    }, 
    "wires":[ 
     { 
     "src":{ 
      "moduleId":1, 
      "terminal":"modbus.connection.output" 
     }, 
     "tgt":{ 
      "moduleId":2, 
      "terminal":"modbus.connection.input" 
     } 
     }, 
     { 
     "src":{ 
      "moduleId":2, 
      "terminal":"modbus.device.output" 
     }, 
     "tgt":{ 
      "moduleId":0, 
      "terminal":"modbus.device.output" 
     } 
     }, 
     { 
     "src":{ 
      "moduleId":3, 
      "terminal":"dataOut" 
     }, 
     "tgt":{ 
      "moduleId":4, 
      "terminal":"dataIn" 
     } 
     }, 
     { 
     "src":{ 
      "moduleId":3, 
      "terminal":"dataIn" 
     }, 
     "tgt":{ 
      "moduleId":0, 
      "terminal":"data1" 
     } 
     } 
    ] 
} 

--Output--

{type=[7], size=3} {type=[4], size=0} - modules 
{type=[4], size=0} - properties 
{type=[4], size=0} - wires 

答えて

20

ますいくつかの電子を持って一見JSONの再帰やkey-> value nature、およびそれがあなたが使用しているライブラリにどのように関係しているかについての素晴らしい扱いを持っていないことに関連しています。私はこのコードを全くテストしていませんが、よりうまくいくはずです。

void CDriverConfigurator::PrintJSONValue(const Json::Value &val) 
{ 
    if(val.isString()) { 
     printf("string(%s)", val.asString().c_str()); 
    } else if(val.isBool()) { 
     printf("bool(%d)", val.asBool()); 
    } else if(val.isInt()) { 
     printf("int(%d)", val.asInt()); 
    } else if(val.isUInt()) { 
     printf("uint(%u)", val.asUInt()); 
    } else if(val.isDouble()) { 
     printf("double(%f)", val.asDouble()); 
    } 
    else 
    { 
     printf("unknown type=[%d]", val.type()); 
    } 
} 

bool CDriverConfigurator::PrintJSONTree(const Json::Value &root, unsigned short depth /* = 0 */) 
{ 
    depth += 1; 
    printf(" {type=[%d], size=%d}", root.type(), root.size()); 

    if(root.size() > 0) { 
     printf("\n"); 
     for(Json::Value::const_iterator itr = root.begin() ; itr != root.end() ; itr++) { 
      // Print depth. 
      for(int tab = 0 ; tab < depth; tab++) { 
       printf("-"); 
      } 
      printf(" subvalue("); 
      PrintJSONValue(itr.key()); 
      printf(") -"); 
      PrintJSONTree(*itr, depth); 
     } 
     return true; 
    } else { 
     printf(" "); 
     PrintJSONValue(root); 
     printf("\n"); 
    } 
    return true; 
} 
+0

私が探していたものです。ありがとうございました。 –

+0

@Steven smethurst:本当に面白いのは、私の人生の前にその図書館を見たことさえないということです。 :-) – Omnifarious

+0

@cegprakash:なぜあなたは 'reference'タグを削除しましたか? – Omnifarious

6

あなただけのJSON ::値をプリントアウトするために探している場合は、そのためのmethodがあります:

Json::Value val; 
/*...build the value...*/ 
cout << val.toStyledString() << endl; 

また、あなたがJson::StyledWriterに見てみたいことがあり、そのためのドキュメントがありますhere。私はそれが人間フレンドリーなバージョンを印刷すると信じています。また、Json::FastWriter、ドキュメントhereは、よりコンパクトなフォームを印刷します。

+0

これは私が探していた出力を生成しますが、JSONツリーをどのように歩いているかを知るためにこの演習を行っていました。ありがとう –

-1

json :: valueのすべてのフィールドを簡単に反復処理する方法があります。私はprintfのものを省いた。

#include "cpprest/json.h" 
#include "cpprest/filestream.h" 

using web::json::value; 
using std::wstring; 

static void printOneValue(const wstring &key, const double &value); 
static void printOneValue(const wstring &key, const bool &value); 
static void printOneValue(const wstring &key, const int &value); 
static void printOneValue(const wstring &key, const wstring &value); 
static void printOne(const wstring &key, const value &v, _num level); 
static void printTree(const value &v); 

static void printTree(const value &v) 
{ 
    if(!v.is_object()) 
     return; 

    try 
    { 
     printOne(wstring(), v, 0); 
    } 
    catch(...) 
    { 
     // error handling 
    } 
} 

static void printOne(const wstring &key, const value &v, _num level) 
{ 
    switch(v.type()) 
    { 
    case value::value_type::Number: 
     if(v.is_double()) 
      printOneValue(key, v.as_double()); 
     else 
      printOneValue(key, v.as_integer()); 
     break; 
    case value::value_type::Boolean: 
     printOneValue(key, v.as_bool()); 
     break; 
    case value::value_type::String: 
     printOneValue(key, v.as_string()); 
     break; 
    case value::value_type::Object: 
     for(auto iter : v.as_object()) 
     { 
      const wstring &k = iter.first; 
      const value &val = iter.second; 
      printOne(k, val, level+1); 
     } 
     break; 
    case value::value_type::Array: 
     for(auto it : v.as_array()) 
     { 
      printOne(key, it, level+1); 
     } 
     break; 
    case value::value_type::Null: 
    default: 
     break; 
    } 
} 

static void printOneValue(const wstring &key, const wstring &value) 
{ 
    // process your key and value 
} 

static void printOneValue(const wstring &key, const int &value) 
{ 
    // process your key and value 
} 

static void printOneValue(const wstring &key, const double &value) 
{ 
    // process your key and value 
} 

static void printOneValue(const wstring &key, const bool &value) 
{ 
    // process your key and value 
} 
+0

このコードは質問に答えるかもしれませんが、どのようにして問題が解決されるのか、なぜそれが解決されるのかについての追加の文脈を提供すると、回答の長期的価値が向上します。質の高い回答を提供するためには、この[how-to-answer](http://stackoverflow.com/help/how-to-answer)をお読みください。 – thewaywewere

+0

ここのサンプルコードはJsonCppに基づいていませんが、まったく別のライブラリです!これはまったく異なる質問に対する答えです。 –

関連する問題