Skipping missing element with RapidJson

In a previous post we have seen how by default RapidJson checks data coherence with C-style assertion, and how we can change this behavior to let it throw an exception instead.

Sometime throwing an exception is an overkill, and asserting should just be avoided. Let think about the case of accessing an element on the JSON document that is not mandatory. If it is there, fine, we can use it, otherwise we should simply skip it. Nothing exceptional or catastrophic is implied by not being it there.

The official RapidJson User Guide, shows as how to use the FindMember() method to get an element or a nullptr in case it is missing. But this is a way you can go through in RapidJson 0.2, that is not currently available to download. If you are using RapidJson 0.1x, you should think to something different.

In my JSON there is an array element named ds, that could contain a few elements. One of them is named "a", and should be a string.

Here is my assertion/exception-free code for this case:
const rapidjson::Value& ds; // 1

// ...

for(rapidjson::SizeType i = 0; i < ds.Size(); ++i) // 2
{
  if(ds[i]["a"].IsNull() || !ds[i]["a"].IsString()) // 3
  {
    // 4
  }
  else
  {
    std::string a(ds[i]["a"].GetString()); // 5
    // ...
  }
}
1. I'll fetch in the variable ds the content of the JSON "ds" element, ensuring it is an array.
2. Loop on all the ds elements.
3. In RapidJson 0.1x, trying to access a non-existing element we get a reference to a null-value singleton. If this is the case, the IsNull() method returns true. Since I expect my "a" element to be a string, I also call IsString() to ensure that.
4. If the "a" element is not there, or if it is not a string, I could take some alternative action, maybe logging some message, if I think the user should be aware of that.
5. Otherwise it is safe to access the "a" element, get its value as a C-string, and use it.

No comments:

Post a Comment