Search code examples
c++arrayscocos2d-xrapidjson

Accessing rapidjson::Document array by index


I have this code:

Document dataDoc;
dataDoc.SetArray();
Document::AllocatorType &allocator = dataDoc.GetAllocator();

for (size_t i = 0; i < 10; ++i)
{
    ostringstream ss;
    ss << "set_" << i + 1 << "_data";

    Document doc;
    doc.Parse<0>(UserDefault::getInstance()->getStringForKey(ss.str().c_str()).c_str());
    dataDoc.PushBack(doc, allocator);
}

There's a rapidjson::Document "dataDoc" and I convert it to an array. Then I fill the array with Document objects that contain JSON objects that are fetched from cocos2d::UserDefault and parsed appropriately.

This is the JSON object that is added to the dataDoc:

{
  "people": [
    {
      "name": "Peter",
      "phone": "123",
      "address": "Address 456"
    },
    {
      "name": "Helen",
      "phone": "123",
      "address": "Address 456"
    },
    {
      "name": "John",
      "phone": "123",
      "address": "Address 456"
    }
  ]
}

Now the dataDoc array contains 10 of these objects.

I know that I can handle one object like this:

Document doc;
rapidjson::Value &people = doc["people"];
string name = people[0]["name"].GetString();

But how can I access, for example, the first object in the dataDoc array by index and get the name value as above?

Edit

Tried also with this code:

vector<string> jsons;
jsons.push_back("{\"people\":[{\"name\":\"Peter\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"Helen\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"John\",\"phone\":\"123\",\"address\":\"Address 456\"}]}");
jsons.push_back("{\"people\":[{\"name\":\"Peter\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"Helen\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"John\",\"phone\":\"123\",\"address\":\"Address 456\"}]}");
jsons.push_back("{\"people\":[{\"name\":\"Peter\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"Helen\",\"phone\":\"123\",\"address\":\"Address 456\"},{\"name\":\"John\",\"phone\":\"123\",\"address\":\"Address 456\"}]}");

Document dataDoc;
dataDoc.SetArray();
Document::AllocatorType &allocator = dataDoc.GetAllocator();

for (size_t i = 0; i < 3; ++i)
{
    Document doc;
    doc.Parse<0>(jsons.at(i).c_str());
    dataDoc.PushBack(doc, allocator);
}

auto &people = dataDoc[0]["people"];

But it gave me the same error. It points to line 1688 in "document.h" located at ...\cocos2d\external\json\.


Solution

  • First, there seems to be an issue in your code the way you create doc - You need to provide the allocator of dataDoc:

    Document doc(&allocator);
    

    Then, rapidjson::Document inherits from rapidjson::Value, so you can simply treat it as a value and use the [] operator:

    auto &people = dataDoc[0]["people"];
    

    You can also iterate through the whole document:

    for (auto &doc: dataDoc.getArray()) {
        auto &people = doc["people"];
    }
    

    Prior to C++11:

    for (Value::ConstValueIterator itr = dataDoc.Begin(); 
         itr != dataDoc.End(); ++itr) {
        auto &people = (*itr)["people"];
    }