Как десериализовать std::map из JSON с помощью библиотек Poco C++

Это связано с другим вопросом, который я задал, но гораздо более конкретным. Мне нужно десериализовать std::map из моих данных JSON.

{
    "name":"john smith"
    "metadata":
    {
        "age":45,
        "middle_name":"william",
    },
}

Я пробовал много, много способов сделать это, и ничего не работает. Основываясь на ответах на предыдущий поток, я подумал, что этот код должен работать.

std::map myMap;
std::string jsonString; // string containing the above JSON
Poco::JSON::Parser jsonParser;
Poco::Dynamic::Var parsedJSON = jsonParser.parse(jsonString);
Poco::Dynamic::Var parsedResult = jsonParser.result();
Poco::DynamicStruct jsonStruct = *parsedResult.extract<Poco::JSON::Object::Ptr>();
Poco::Dynamic::Var mapVar = jsonStruct["stdmap_data"];
for (Poco::Dynamic::Var::ConstIterator itr = mapVar.begin(), end = mapVar.end(); itr != end; ++itr)
    myMap[itr->first().toString()] = itr->second().toString();

К сожалению, у этого итератора нет "первого" и "второго" членов. Я пробовал DynamicStruct (та же проблема) и JSON::Object (не могу/не буду конвертировать из jsonStruct["stdmap_data"]).

Это кажется чем-то ОЧЕНЬ распространенным в данных JSON, поэтому я был бы шокирован, если бы Poco C++ не смог этого сделать. Кто-нибудь знает, как это должно быть сделано?


person Bungles    schedule 15.05.2015    source источник


Ответы (2)


Ответил здесь .

Для справки, вот фрагмент функции, которая распечатает любой объект, включая вложенные:

void objPrint(Object& obj, const std::string& name = "")
{
    for (Object::ConstIterator it = obj.begin(),
        end = obj.end(); it != end; ++it)
    {
        if (!name.empty()) std::cout << name << ':';
        std::cout << it->first << ':';
        if (it->second.type() == typeid(Object::Ptr))
        {
            Object::Ptr p = it->second.extract<Object::Ptr>();
            objPrint(*p, it->first);
        }
        else
             std::cout << it->second.toString() << std::endl;
    }
}
person Alex    schedule 17.05.2015
comment
Какие из моих переменных выше я должен передать в функцию «objPrint»? У меня нет JSON::Object для передачи в функцию. - person Bungles; 17.05.2015
comment
Этот код не отвечает на вопрос, поскольку не показывает, как извлечь вложенные данные в std::map. Более того, когда я пытаюсь использовать этот код, я получаю poco\include\poco\dynamic\var.h(199): error C2664: 'void Poco::Dynamic::VarHolder::convert(Poco::UTF16String &) const' : невозможно преобразовать аргумент 1 из "Poco::JSON::Object" в "Poco::Int8 &" - person Bungles; 17.05.2015

Вот что сработало:

// Deserialize from JSON
void DeserializeFromJSON(string &jsonString)
{
    // Parse the JSON
    Poco::JSON::Parser jsonParser;
    Poco::Dynamic::Var parsedJSON = jsonParser.parse(jsonString);
    Poco::Dynamic::Var parsedResult = jsonParser.result();

    // Extract top-level fields
    Poco::DynamicStruct jsonStruct = *parsedResult.extract<Poco::JSON::Object::Ptr>();
    name = jsonStruct["identifier"].toString();

    // Get metadata nested fields
    string keyStr = "metadata";
    Poco::JSON::Object::Ptr jsonObject = parsedResult.extract<Poco::JSON::Object::Ptr>();
    Poco::Dynamic::Var metaVar = jsonObject->get(keyStr);
    Poco::JSON::Object::Ptr metaObj = metaVar.extract<Poco::JSON::Object::Ptr>();
    for (Poco::JSON::Object::ConstIterator itr = metaObj->begin(), end = metaObj->end(); itr != end; ++itr)
        metaData[itr->first] = itr->second.toString();
}

Казалось бы, DynamicStruct нельзя использовать для вложенных полей.

person Bungles    schedule 17.05.2015
comment
См. [stackoverflow.com/questions/30248751/ - person Christian Severin; 04.11.2015