将rapidjson数组迭代器转换为rapidjson :: value

时间:2017-06-07 18:38:25

标签: c++ rapidjson

如何将rapidjson数组迭代器转换为rapidjson :: value?

我不希望答案专注于如何获取快速json数组的内容,或者如何迭代它。

我也非常清楚我可以使用rapidjson文档itr->name中的示例通过迭代器访问成员,但这不是我想要的。使用rapidjson数组的这种形式已经出现在许多堆栈溢出问题和rapidjson文档中,并已被覆盖。

在使用rapidjson数组迭代器开始时,我需要以rapidjson::value结束。

如果我们有std::vector<int>,我们可以分配

std::vector<int>::iterator itMyInt = myvector.begin();
const int & myInt = *itMyInt;

我希望能用rapidjson数组迭代器做同样的事情,但我的编译器不同意。

我需要一个rapidjson :: value的原因是,当我是一个数组元素时,我想重用相同的解析方法来解析json对象,就像我自己解析该对象时一样。不在数组中。

让我用最小的例子来证明:

// Rapid JSON Includes
#include <rapidjson/Document.h>
#include <rapidjson/StringBuffer.h>
#include <rapidjson/writer.h>

// Standard Includes
#include <exception>
#include <string>
#include <sstream>

//--------------------------------------------------------------------------------------------------
// NOTE -This stub cannot change
void ParseCar(const rapidjson::Value & carJson)
{

}

//--------------------------------------------------------------------------------------------------
int main()
{
    std::string json =
        "{"
        "    \"cars\" : ["
        "    {"
        "        \"name\" : \"Fiat\","
        "        \"price\" : 19.95"
        "    },"
        "    {"
        "        \"name\" : \"FRS\","
        "        \"price\" : 19995.00"
        "    }]"
        "}";

    // Parse the JSON
    rapidjson::Document document;
    document.Parse(json.c_str());

    if (document.HasParseError())
    {
        // Error - Failed to parse JSON
        std::ostringstream msg;
        msg << "There was an error parsing the JSON"
            << " Error Code: " << document.GetParseError()
            << " Error Offset: " << document.GetErrorOffset();

        throw std::exception(msg.str().c_str());
    }

    // Cars array
    if (!document.HasMember("cars") ||
        !document["cars"].IsArray())
    {
        std::string msg("Expected \"cars\"  JSON array");

        throw std::exception(msg.c_str());
    }

    const rapidjson::Value & carsArrayJSON = document["cars"];

    /* Doesn't compile - No GetArray method exists
    for (auto & carJSON : carsArrayJSON.GetArray())
    {

    }
    */


    for (rapidjson::Value::ConstMemberIterator itCarJSON = carsArrayJSON.MemberBegin(); itCarJSON != carsArrayJSON.MemberEnd(); ++itCarJSON)
    {
        // Error - const rapidjson::GenericMember<Encoding,Allocator>' to 'const rapidjson::Value
        const rapidjson::Value & carJSON = *itCarJSON;

        ParseCar(carJSON);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

SELECT迭代对象的成员。 INDEX迭代数组中的值。

另外,我不确定为什么这个循环对你有问题,这为我编译:

MemberIterator

并返回:

ValueIterator

至于在循环中应用函数:

std::string json =
    "{"
    "    \"cars\" : ["
    "    {"
    "        \"name\" : \"Fiat\","
    "        \"price\" : 19.95"
    "    },"
    "    {"
    "        \"name\" : \"FRS\","
    "        \"price\" : 19995.00"
    "    }]"
    "}";
Document doc;
doc.Parse(json.data());
Value const& cars = doc["cars"];
for (auto& car : cars.GetArray()) {
    cout << "name: " << car["name"].GetString() << " "
        << "price: " << car["price"].GetFloat() << endl;
}

如果必须使用迭代器:

name: Fiat price: 19.95
name: FRS price: 19995

或使用自动:

for (Value& car : cars.GetArray()) {
    ParseCar(car);
}

答案 1 :(得分:0)

注意:这只适用于数组。

最近,我遇到了类似的问题,我采用了不同的方法。

首先,我设置一个指向所需路径的指针,如下所示:

int myIterator = 0;
string myString = "/Layer1/Layer2/" + to_string(myIterator);
Pointer p(myString.c_str());

我现在有一个指向我的JSON对象中的变量路径的指针,该变量路径随myIterator而变化。

然后,我只使用了一个for循环,其中我使用SetValueByPointer函数将指针的值附加到JSON对象。