невозможно определить тип quickjson / трудно читать тройные вложенные строки - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь использовать злаки для десериализации сообщения JSON. (Текущая) структура сообщения следующая:

"A":"B",
"C":{"D":"E","F":"G","H":"I"},
"J":"K",
"L":"M",
"N":{"O":{"P":"Q"}}}

Самым важным элементом данных является «Q». Я могу читать все нормальные строки легко. Я мог легко читать предметы верхнего уровня. В конце концов я смог прочитать «D» - «I», рассматривая «C» как массив (несмотря на отсутствие «[» и «]»). Однако я не могу заархивировать «N» как строку, массив, вектор или объект. Он просто не проходит соответствующую проверку IsString (), IsObject () и т. Д. В строке iarchive(C);. Я вижу GetType(), но я не знаю, как это назвать на «N», потому что все, что я пытаюсь сделать с «N», терпит неудачу.

Я тогда смог разорвать строку до

{"O":{"P":"Q"}}

отлично, так что просто "С", но еще проще. К сожалению, у меня была та же проблема, что и раньше.

Затем я разбил его до {"P": "Q"} и смог наконец получить значение Q с помощью iarchive(value)

std::string msgtype,protocol_version, command, radio1_frequency,value;
    std::string unit_id[3];
    std::stringstream ss(msg->get_payload());
    {//at this point, ^ss has  the same format as outlined above, from "A" to "Q."
        cereal::JSONInputArchive iarchive(ss);
        iarchive(CEREAL_NVP(msgtype), CEREAL_NVP(protocol_version), CEREAL_NVP(command),CEREAL_NVP(unit_id));<-----------------------
    }
    rapidjson::Document doc;
    doc.Parse((msg->get_payload()).c_str());
    const rapidjson::Value& vars = doc["variables"];//<--this string is N
    rapidjson::StringBuffer sb;
    rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
    vars.Accept(writer);
    std::stringstream sst(sb.GetString());
    std::cout << sst.str() << "\n"; //here, sst has {"O":{"P":"Q"}}
    doc.Parse(sb.GetString());

    const rapidjson::Value& val = doc["radio1_frequency"];//<--this string is O
    sb.Clear();
    rapidjson::Writer<rapidjson::StringBuffer> writerTwo(sb);
    val.Accept(writerTwo);
    std::cout << sb.GetString() << "\n";//ss3 will now have {"P":"Q"} 
    std::stringstream ss3(sb.GetString());
    {
        cereal::JSONInputArchive iarchive(ss3);
        iarchive((value));
        std::cout << value << '\n';//Q
    }

если я добавлю ,CEREAL_NVP(variables) к строке со стрелкой, я получу следующий вывод:

terminate called after throwing an instance of 'cereal::RapidJSONException'
  what():  rapidjson internal assertion failure: IsString()

Child terminated with signal = 0x6 (SIGABRT)

Чтобы было ясно, я получаю желаемый результат, Q. Я просто чувствую, что должен быть лучший способ. Я чувствую, что корень проблемы в том, что я не могу определить, что такое тип N. Поскольку я не знаю тип, я не знаю, как правильно заархивировать его в зерновых. Что я могу сделать лучше в области C ++ 11 и зерновых, которые используют rapidjson?

Интересно, так ли это, потому что у "O" есть число в середине строки, и это отбрасывает его? Надеюсь, что нет, потому что это верная строка, я верю

редактировать: я забыл упомянуть, что «О» может измениться. поэтому я не смогу жестко закодировать это в doc["N"]["O"]["P"]

...