2015-03-07 23 views
6

Mam zagnieżdżony obiekt JSON. Próbuję zbudować go w funkcji i dodać obiekt wewnętrzny do oryginału, ale nie mogę wyodrębnić wyniku.Poco C++ budowanie zagnieżdżonych obiektów JSON

void build_object (Poco::JSON::Object * const result) 
{ 

    /* Construct some int/bool/string fields here */ 

    Poco::JSON::Object inner; 
    inner.set("some_number", 5); 
    inner.set("some_string", "xyz"); 

    /* This is where it breaks down */ 
    std::string key = "new_object"; 
    result->set("new_object", inner); 

    /* Then some debugging and testing */ 
    // The new object is printed inside the first -> seems like it's working 
    result->stringify(std::cout); 

    printf("result has(key): %i\n", result->has(key)); // true 
    printf("isObject: %i\n", result->isObject(key)); // false - huh? 
    printf("isNull: %i\n", result->isNull(key));  // false 
    printf("isArray: %i\n", result->isArray(key));  // false 

    Poco::JSON::Object::Ptr ptr = result->getObject(key); 
    // unsurpisingly fails since the above indicates it's not an object 
    printf("ptr isNull: %i\n", ptr.isNull());   // true 
    // ptr->has("some_number"); // throws NullPointerException 

    // if it's not an object/null/array, it must be a value 
    Poco::Dynamic::Var v = result->get(key); 
    // at least one of these things should be true, otherwise what is it? 
    printf("var isString: %i\n", v.isString()); // false 
    printf("var isStuct: %i\n", v.isStruct()); // false 
    printf("var isEmpty: %i\n", v.isEmpty()); // false 
    printf("var isArray: %i\n", v.isArray()); // false 
    printf("var isSigned: %i\n", v.isSigned()); // false 
    printf("var isNumeric: %i\n", v.isNumeric());// false 
} 

Tak, mam wewnętrzną obiekt, który jest prawidłowo wprowadzone do wyniku, to jest drukowane przez stringify ze wszystkimi poprawnymi wartościami i result-> ma() zakończy się pomyślnie. Ale, zgodnie z wynikiem, nie jest to obiekt, tablica ani wartość null, więc powinieneś być w stanie go uzyskać z var. Ale po pobraniu z var, nie jest to ciąg, struktura, tablica ani liczba, a także nie jest pusty. Wewnętrzny obiekt wydaje się istnieć i nie istnieje w tym samym czasie.

Jak umieścić ten obiekt w moim wyniku? I jak mam to wydobyć?

Dzięki

uwaga: Widziałem ten wątek Correct usage of Poco C++ JSON for parsing data, ale buduje obiekt JSON z łańcucha, a następnie analizowania go. Sądzę, że mógłbym wszystko zbudować jako strunę i przejść na Poco Object na ostatnim etapie, ale wciąż jestem ciekawy, dlaczego to się dzieje. Ponadto użycie result-> set() i result-> get() jest czystszym, mniej hack-y rozwiązaniem niż przejściem przez string.

Referencje: Poco JSON Doc, Poco Dynamic Var Doc

+0

Jaki jest rodzaj powrotu do '' result-> has' result-> isObject' itp? Jeśli jest to 'bool', to niezdefiniowanym zachowaniem jest użycie' bool' w instrukcji 'printf()', ponieważ nie ma oficjalnego specyfikatora formatu dla 'bool'. – PaulMcKenzie

+0

Typ powrotu to bool. Zamieniam true i false na 1 i 0 w moich komentarzach powyżej. To nie jest problem z drukowaniem - mogę rzucić je wszystkie do int i uzyskać ten sam wynik, także jako bardziej przekonujący test obiektów zerowych, próbując użyć ptr z 'ptr = result-> getObject (key)' zgłasza wyjątek wskaźnika pustego – stebl

Odpowiedz

7

Poco :: JSON Obiekty i tablice są przechowywane jako wspólne wskaźniki wewnętrznie domyślnie (optymalizacja aby uniknąć wartości skopiowania) i wszystko jest dynamiczne :: Var, tak to działa dla obu wskaźników i wartości. Kiedy wstawiasz obiekt jako wartość, działa on, ponieważ Dynamic :: Var będzie zawierał prawie wszystko, ale problem, którego doświadczasz podczas sprawdzania, pochodzi z faktu, że wewnętrzne porównanie nie zwraca wartości true dla wartości Object, ponieważ porównuje tylko z typem domyślnym - Poco :: SharedPtr < Poco :: JSON :: Obiekt >.

Oto obejście:

void build_object (Poco::JSON::Object * const result) 
{ 
    // smart pointer, so don't worry about cleaning up 
    Poco::JSON::Object::Ptr inner = new Poco::JSON::Object; 
    inner->set("some_number", 5); 
    inner->set("some_string", "xyz"); 

    std::string key = "new_object"; 
    result->set(key, inner); 
    printf("isObject: %i\n", result->isObject(key)); // true 
} 

I otworzyły github issue złagodzić to zastrzeżenie.

+0

dokładnie to, czego szukałem, dzięki! – stebl

2

Próbowałem utworzyć plik json zawierający obiekt zagnieżdżony za pomocą biblioteki poco. Wreszcie można zrobić z Poco :: Json :: Array.

Proszę znaleźć wysłany kod sinippet. Mam nadzieję, że to pomoże. Wyjście Json dołączone z postem.

#include "Poco\JSON\JSON.h" 
#include "Poco\JSON\Stringifier.h" 
#include "Poco\JSON\Object.h" 
#include "Poco\Dynamic\Var.h" 


using namespace std; 
using Poco::JSON::Stringifier; 
using Poco::JSON::Object; 
using Poco::JSON::Array; 

     void makeJsonNestedObject() 
    { 
     Object RootObj(true); 
     Array FLArray; 

     for(int i=0; i<3; i++) 
     {  
      Object::Ptr FirstLevelArrayNode = new Poco::JSON::Object(true); 
      TCHAR strNameBuff[15]; 
      _stprintf(strNameBuff, _T("%s_%d"),_T("Servername"),i); 
      std::basic_string<TCHAR> strName = strNameBuff; 


      FirstLevelArrayNode->set("HostName", strName); 
      FirstLevelArrayNode->set("Overall Impact", "Dummy Data"); 

      Array SLArray; 

      for(int j=0; j<3;j++) 
      { 
       Object::Ptr SecondLevelArrayNode = new Poco::JSON::Object(true); 
       TCHAR attr1NameBuff[15]; 
       TCHAR attr2NameBuff[15]; 
       _stprintf(attr1NameBuff, _T("%s_%d"),_T("AttrOne"),j); 
       _stprintf(attr2NameBuff, _T("%s_%d"),_T("AttrTwo"),j); 
       std::basic_string<TCHAR> attr1Name = attr1NameBuff; 
       std::basic_string<TCHAR> attr2Name = attr2NameBuff; 
       SecondLevelArrayNode->set("Attribute", attr1Name); 
       SecondLevelArrayNode->set("SubAttribute", attr2Name); 
       Poco::Dynamic::Var obj(SecondLevelArrayNode); 
       SLArray.add(obj); 
      } 
      FirstLevelArrayNode->set("Attribute_Details",SLArray); 
      Poco::Dynamic::Var FLArrayNodeobj(FirstLevelArrayNode); 
      FLArray.add(FLArrayNodeobj); 

     } 
     std::ostringstream os; 
     std::cout <<"before stringlify.." << std::endl; 
     FLArray.stringify(os, 2); 
     std::cout << os.str() << std::endl; 

    } 

wyjście Json:

[ 
    { 
    "HostName" : "Servername_0", 
    "Overall Impact" : "Dummy Data", 
    "Attribute_Details" : [ 
     { 
     "Attribute" : "AttrOne_0", 
     "SubAttribute" : "AttrTwo_0" 
     }, 
     { 
     "Attribute" : "AttrOne_1", 
     "SubAttribute" : "AttrTwo_1" 
     }, 
     { 
     "Attribute" : "AttrOne_2", 
     "SubAttribute" : "AttrTwo_2" 
     } 
    ] 
    }, 
    { 
    "HostName" : "Servername_1", 
    "Overall Impact" : "Dummy Data", 
    "Attribute_Details" : [ 
     { 
     "Attribute" : "AttrOne_0", 
     "SubAttribute" : "AttrTwo_0" 
     }, 
     { 
     "Attribute" : "AttrOne_1", 
     "SubAttribute" : "AttrTwo_1" 
     }, 
     { 
     "Attribute" : "AttrOne_2", 
     "SubAttribute" : "AttrTwo_2" 
     } 
    ] 
    }, 
    { 
    "HostName" : "Servername_2", 
    "Overall Impact" : "Dummy Data", 
    "Attribute_Details" : [ 
     { 
     "Attribute" : "AttrOne_0", 
     "SubAttribute" : "AttrTwo_0" 
     }, 
     { 
     "Attribute" : "AttrOne_1", 
     "SubAttribute" : "AttrTwo_1" 
     }, 
     { 
     "Attribute" : "AttrOne_2", 
     "SubAttribute" : "AttrTwo_2" 
     } 
    ] 
    } 
] 
Powiązane problemy