2011-01-26 112 views
20

我有一个C++应用程序,它使用jsoncpp来解码JSON字符串。我创建了以下功能,但它只显示顶级对象...遍历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

你有一些e看起来似乎没有很好的递归处理或者JSON的关键 - >价值性质,以及与你正在使用的库有什么关系。我还没有测试过这个代码,但它应该更好。

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

正是我在找的东西。谢谢。 – 2011-01-26 17:44:53

+0

@Steven smethurst:真正有趣的是我以前从来没有看过那个图书馆。 :-) – Omnifarious 2011-05-11 02:00:57

+0

@cegprakash:你为什么删除'reference'标签? – Omnifarious 2013-01-05 22:57:31

6

如果你只是希望打印出的Json ::值,有一个为一个method

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

此外,你可能想看看进入Json::StyledWriter,因为它的文档here。我相信它打印出一个人性化的版本。此外,Json::FastWriter,文档here,打印更紧凑的形式。

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