Poco C++ 构建嵌套 JSON 个对象

Poco C++ building nested JSON objects

我有一个嵌套的 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->has() 成功。但是,根据结果来看,它不是对象,也不是数组,也不是null,所以用var应该可以得到。但是,一旦它从 var 获得,它就不是字符串、结构、数组或数字,也不是空的。内在客体似乎同时存在又不存在。

那么,如何将此对象放入我的结果中?我该如何取出它?

谢谢

注意:我看过这个线程 Correct usage of Poco C++ JSON for parsing data,但它正在从字符串构建 JSON 对象,然后对其进行解析。我想我可以将所有内容构建为字符串并在最后一步转换为 Poco 对象,但我仍然很好奇为什么会发生上述情况。此外,使用 result->set() 和 result->get() 是一种比通过字符串更简洁、更简单的解决方案。

参考文献:Poco JSON DocPoco Dynamic Var Doc

Poco::JSON 默认情况下,对象和数组在内部作为共享指针保存(优化以避免值复制)并且一切都是 Dynamic::Var,因此它适用于指针和值。当您插入一个 Object 作为值时,它可以工作,因为 Dynamic::Var 几乎可以容纳任何东西,但是您在检查它时遇到的问题来自于内部比较对于 Object 值不 return true 因为它比较仅使用默认类型 - Poco::SharedPtr.

解决方法如下:

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 来缓解这个警告。

我一直在尝试使用 poco 库创建具有嵌套对象的 json 文件。终于可以用Poco::Json::Array了。

请找到 posted 代码片段。希望它会有所帮助。 Json 附有 post 的输出。

#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"
      }
    ]
  }
]