2011-01-26 7 views
20

Tôi có một ứng dụng C++ sử dụng jsoncpp để giải mã một chuỗi JSON. Tôi đã tạo ra các chức năng sau đây nhưng nó chỉ cho tôi thấy các đối tượng cấp cao nhất ...lặp lại thông qua các đối tượng trong JsonCpp

Làm thế nào để có được nó để đổ toàn bộ danh sách đối tượng?

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

--- Input ----

{ 
    "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 

Trả lời

20

Bạn có một số e có liên quan đến việc dường như không có một xử lý tuyệt vời về đệ quy hoặc bản chất khóa-> giá trị của JSON và cách liên quan đến thư viện bạn đang sử dụng. Tôi chưa thử nghiệm mã này, nhưng nó sẽ hoạt động tốt hơn.

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

Chính xác những gì tôi đang tìm kiếm. Cảm ơn bạn. –

+0

@Steven smethurst: Điều thực sự thú vị là tôi chưa từng xem thư viện đó trước đây trong cuộc đời mình. :-) – Omnifarious

+0

@cegprakash: Tại sao bạn xóa thẻ 'tham chiếu'? – Omnifarious

6

Nếu bạn chỉ muốn in ra Json :: Giá trị, có một method cho rằng:

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

Ngoài ra, bạn có thể muốn nhìn vào Json::StyledWriter, tài liệu cho nó là here. Tôi tin rằng nó in một phiên bản thân thiện với con người. Ngoài ra, Json::FastWriter, tài liệu here, in một biểu mẫu nhỏ gọn hơn.

+0

Điều này tạo ra kết quả đầu ra mà tôi đang tìm kiếm nhưng tôi đã thực hiện bài tập này để tìm hiểu cách đi bộ cây JSON. Cảm ơn –

-1

Có một cách dễ dàng để lặp qua tất cả các trường trong giá trị json ::. Tôi bỏ qua những thứ 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

Mặc dù mã này có thể trả lời câu hỏi, cung cấp thêm ngữ cảnh về cách thức và/hoặc lý do giải thích vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời. Vui lòng đọc [cách trả lời] này (http://stackoverflow.com/help/how-to-answer) để cung cấp câu trả lời có chất lượng. – thewaywewere

+0

Mã ví dụ ở đây thậm chí không dựa trên JsonCpp, mà là một thư viện hoàn toàn khác! Đây là câu trả lời cho một câu hỏi hoàn toàn khác. –