RapidJSON – Part 1 – Dumping All Tags


One of the best ways of working with a new API or library is to try to strip something apart using basic commands. In the case of RapidJSON I had to do this because the documentation is minimal at best. I also found the Doxygen listings to be poor so someone was in a big hurry to get it working but not prepared to document it.

I decided to write a program to strip apart a JSON message and dump the top level tags, then for each top level tag that was an object (using the value.IsObject() method) iterate through it and print the tags found along with their data types.

What the example shows is the following:

  • Parsing a file using ParseStream<0>
  • Detecting a Parse Error (using HasParseError())
  • iterating through a Document object
  • determining data types and
  • using the Value object

RapidJSON has 4 basic data types, “Object“, “Array“, “String” and “Number” so we can process the value the right way when we know its data type.

The code

// JSON dump all tags example

#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"
#include "rapidjson/filestream.h"

#include 
#include 

using namespace rapidjson;
using namespace std;

int main(int argc, char**argv)
{
static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };

    FILE * fp = fopen(argv[1],"r");
    FileStream is(fp);
    Document doc;

    if(doc.ParseStream(is).HasParseError()==true)
    {
        cout << "Parsing error" << endl;
        return 1;
    }
    else
else
    {
        cout<<"\nDocument scan"<<endl;         for (Value::ConstMemberIterator itr = doc.MemberBegin(); itr != doc.MemberEnd(); ++itr)         {             printf("Member [%s] - type is [%s]\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);
            if(itr->value.IsObject()==true)
            {
                cout<< "Process Object ["<name.GetString()<<"]"<<endl;                 string s = itr->name.GetString();
                Value &v = doc[s.c_str()];  // takes a "C" char*
                if(v.IsObject()) cout<< "Its an object"<<endl;
                if(v.IsArray()) cout<< "Its an Array"<<endl;
                if(v.IsString()) cout<< "Its a String"<<endl;
                if(v.IsNumber()) cout<< "Its a Number"<<endl;                 for (Value::ConstMemberIterator it = v.MemberBegin(); it != v.MemberEnd(); ++it)                 {                     printf("Member [%s] is %s ", it->name.GetString(), kTypeNames[it->value.GetType()]);
                    if(it->value.IsString()) cout<< "Value is ["<< it->value.GetString()<<  "]"<<endl;

                }
            }
                cout<<"\n"<<endl;
        }

    }
    return 0;
}

Key Points

Iterating through the document is done using:

for(Value::ConstMemberIterator itr = doc.MemberBegin();itr != doc.MemberEnd(); ++itr)

and we can then decide is data type using if statements, in this case to test if its an object I used:

if(itr->value.IsObject()==true)
{
… we have an object
}

We can get the name of the value using string s = itr->name.GetString(); and I found the best way to get the Value of that object using Value &v = doc[s.c_str()]; but this might not work if there are multiple occurrences of the tag with the same name.

Git Repository

Recently updated: https://github.com/miloyip/rapidjson

-oOo-

Advertisements

2 thoughts on “RapidJSON – Part 1 – Dumping All Tags”

  1. Did you compile your code !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s