2011-01-26 16 views
20

'daki nesneler arasında yineleme Bir JSON dizesinin kodunu çözmek için jsoncpp kullanan bir C++ uygulamasına sahibim. Aşağıdaki işlevi oluşturdum ama yalnızca bana en üst düzey nesneleri gösterir ...JsonCpp

Tüm nesne listesini dökmek için nasıl alabilirim?

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

--- Girdi ----

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

cevap

20

You biraz e Görünüşte, özyinelemede ya da JSON'un anahtar-> değer doğasında ve kullandığınız kitaplık ile ilgili olarak büyük bir sapa sahip olmamaya dair ritimler. Bu kodu hiç test etmedim, ama daha iyi çalışmalı. Sadece JSON :: Değer çıktısını isteyen varsa

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

Tam olarak aradığım şey. Teşekkür ederim. –

+0

@Steven smethurst: Gerçekten eğlenceli olan şey, hayatımda daha önce o kütüphaneye hiç bakmadığım. :-) – Omnifarious

+0

@cegprakash: 'Referans' etiketlerini neden kaldırdınız? – Omnifarious

6

, bunun için bir method var: Ayrıca

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

, sen Json::StyledWriter içine bakmak isteyebilirsiniz, bunun için belgelerdir here. İnsan dostu bir versiyonunu yazdırdığına inanıyorum. Aynı zamanda,, belgeler here, daha kompakt bir form yazdırır.

+0

Bu, aradığım çıktıyı üretir ancak JSON ağacının nasıl yürüdüğünü öğrenmek için bu egzersizi yapıyordum. Teşekkürler –

-1

json :: değerindeki tüm alanlar üzerinde yineleme yapmanın kolay bir yolu vardır. Printf malzemelerini ihmal ettim.

#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

Bu kod soruyu yanıtlarken, sorunun nasıl ve/veya neden çözüldüğüne dair ek bağlam sağlayarak yanıtın uzun vadeli değerini artıracaktır. Lütfen, kalite cevabı sağlamak için bu [nasıl yapılır] (http://stackoverflow.com/help/how-to-answer) okuyun. – thewaywewere

+0

Buradaki örnek kod, JsonCpp'e dayanmıyor, ancak tamamen farklı bir kütüphane! Yani bu tamamen farklı bir sorunun cevabı. –