Разобрать массив JSON с помощью casablanca

Я пытаюсь прочитать ответ JSON в Касабланке. Отправляемые данные выглядят так:

{
"devices":[
  {"id":"id1",
   "type":"type1"},
  {"id":"id2",
   "type":"type2"}
]
}

Кто-нибудь знает как это сделать? Учебники Casablanca, кажется, заботятся только о создании таких массивов, а не о чтении из них.


person spiralstatic    schedule 03.03.2015    source источник


Ответы (2)


Предположим, вы получили свой json в качестве http-ответа:

web::json::value json;
web::http::http_request request;

//fill the request properly, then send it:

client
.request(request)
.then([&json](web::http::http_response response)
{
    json = response.extract_json().get();
})
.wait();

Обратите внимание, что здесь не выполняется проверка ошибок, поэтому давайте предположим, что все работает нормально (если нет, см. документацию и примеры Casablanca).

Затем возвращенный json можно прочитать с помощью функции at(utility::string_t). В вашем случае это массив (вы либо знаете это, либо проверяете через is_array()):

auto array = json.at(U("devices")).as_array();
for(int i=0; i<array.size(); ++i)
{
     auto id = array[i].at(U("id")).as_string();
     auto type = array[i].at(U("type")).as_string();
}

При этом вы получаете записи ответа json, хранящиеся в строковых переменных.

На самом деле вы также можете проверить, есть ли в ответе соответствующие поля, например. через has_field(U("id")), и если да, проверьте, не являются ли записи null через is_null() -- в противном случае функция as_string() выдает исключение.

person davidhigh    schedule 22.10.2015

Ниже приведена рекурсивная функция, которую я сделал для анализа значений JSON в cpprestsdk, если вам нужна дополнительная информация или уточнение, не стесняйтесь спрашивать.

std::string DisplayJSONValue(web::json::value v)
{
    std::stringstream ss;
    try
    {
        if (!v.is_null())
        {
            if(v.is_object())
            {
                // Loop over each element in the object
                for (auto iter = v.as_object().cbegin(); iter != v.as_object().cend(); ++iter)
                {
                    // It is necessary to make sure that you get the value as const reference
                    // in order to avoid copying the whole JSON value recursively (too expensive for nested objects)
                    const utility::string_t &str = iter->first;
                    const web::json::value &value = iter->second;

                    if (value.is_object() || value.is_array())
                    {
                        ss << "Parent: " << str << std::endl;

                        ss << DisplayJSONValue(value);

                        ss << "End of Parent: " << str << std::endl;
                    }
                    else
                    {
                        ss << "str: " << str << ", Value: " << value.serialize() << std::endl;
                    }
                }
            }
            else if(v.is_array())
            {
                // Loop over each element in the array
                for (size_t index = 0; index < v.as_array().size(); ++index)
                {
                    const web::json::value &value = v.as_array().at(index);

                    ss << "Array: " << index << std::endl;
                    ss << DisplayJSONValue(value);
                }
            }
            else
            {
                ss << "Value: " << v.serialize() << std::endl;
            }
        }
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
        ss << "Value: " << v.serialize() << std::endl;
    }

    return ss.str();
}
person Aleksandr    schedule 13.12.2016
comment
Просто для справки в будущем помните, что пользователи могут вернуться к этому сообщению, и это приведет к дополнительным вопросам по этому ответу. Лучше всего добавить всю необходимую информацию, чтобы избежать этого. - person Dennington-bear; 13.12.2016