2015-03-07 7 views
6

У меня есть вложенный объект JSON. Я пытаюсь построить его в функции и добавить внутренний объект к оригиналу, но я не могу извлечь результат.Poco C++ здания вложенные объекты 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 
} 

Итак, у меня есть внутренний объект, который правильно поместить в результат, она печатается через stringify с правильными значениями и result-> имеет() является успешным. Но, в соответствии с результатом, это не объект, массив или нуль, поэтому вы можете получить его с помощью var. Но, как только он получен из var, это не строка, структура, массив или число, а также не пусто. Внутренний объект, кажется, существует и не существует одновременно.

Итак, как я могу поместить этот объект в свой результат? И как мне это понять?

Благодаря

примечание: Я видел эту тему Correct usage of Poco C++ JSON for parsing data, но строит объект JSON из строки, а затем разбор его. Полагаю, я мог бы построить все как строку и преобразовать в объект Poco на последнем шаге, но мне все еще интересно, почему это происходит. Кроме того, использование result-> set() и result-> get() является более чистым, менее разрешенным решением, чем прохождение строки.

Ссылки: Poco JSON Doc, Poco Dynamic Var Doc

+0

Что возвращаемый тип для 'result-> has'' result-> isObject' и т.д.? Если это 'bool', то это неопределенное поведение для использования' bool' в '' printf() ', поскольку для' bool' нет официального спецификатора формата. – PaulMcKenzie

+0

возвращение type - bool. Я заменяю true и false для 1 и 0 в моих комментариях выше. Это не проблема с печатью - я могу отнести их все к int и получить тот же результат, а также в качестве более убедительного теста на нулевой объект, пытаясь использовать ptr из 'ptr = result-> getObject (key)' выбрасывает исключение нулевого указателя – stebl

ответ

7

Poco :: JSON объекты и массивы проводятся как общие указатели внутри по умолчанию (оптимизация, чтобы избежать копирования значений) и все это Dynamic :: Var, так что он работает для обоих указателей и значения. Когда вы вставляете объект как значение, он работает, потому что Dynamic :: Var будет хранить почти все, но проблема, которую вы испытываете при ее проверке, исходит из того факта, что внутреннее сравнение не возвращает true для значений Object, потому что оно сравнивается только с типом по умолчанию - Poco :: SharedPtr < Poco :: JSON :: Объект >.

Вот обходной путь:

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 
} 

Я открыл github issue, чтобы облегчить этот нюанс.

+0

точно, что я искал, спасибо! – stebl

2

Я пытаюсь создать файл json с вложенным объектом, используя библиотеку poco. Наконец, можно сделать с Poco :: Json :: Array.

Пожалуйста, найдите найденный код sinippet. Надеюсь, это поможет. Выход Json прикреплен к сообщению.

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

    } 

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" 
     } 
    ] 
    } 
] 
Смежные вопросы