Click here to Skip to main content
15,896,118 members
Articles / Web Development / HTML

JSON Spirit: A C++ JSON Parser/Generator Implemented with Boost Spirit

Rate me:
Please Sign up or sign in to vote.
4.92/5 (110 votes)
10 May 2014MIT12 min read 4.2M   24.3K   287  
A C++ JSON parser/generator written using Boost::spirit
<!--------------------------------------------------------------------------->  
<!--                           INTRODUCTION                                

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just 
follow the 3 easy steps below:
 
     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets. 

-->  
<!--------------------------------------------------------------------------->  
<!--                        IGNORE THIS SECTION                            -->
<html>
<head>
<title>The Code Project</title>
<Style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<!link rel="stylesheet" type=text/css href="http://www.codeproject.com/styles/global.css">
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!--------------------------------------------------------------------------->  


<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->

<pre>
Title:       JSON Spirit - a C++ JSON parser/generator implemented with Boost Spirit
Author:      John W. Wilkinson 
Email:       john.wilk161c5@googlemail.com
Member ID:   4393813
Language:    C++
Platform:    platform independent
Technology:  boost::spirit
Level:       intermediate
Description: A C++ JSON parser/generator written using boost::spirit
Section      C++ / MFC
SubSection   Parsers
</pre>

<!-------------------------------     STEP 2      --------------------------->
<!--  Include download and sample image information.                       --> 

<ul class=download>
<li><a href="json_spirit_src.zip">Download source - 24 Kb</a></li>
</ul>

<!-------------------------------     STEP 3      --------------------------->
<!--  Add the article text. Please use simple formatting (<h2>, <p> etc)   --> 

<h2>Introduction</h2>

<p><a href="http://www.json.org">JSON</a> is an ASCII file format similar to XML but less verbose. 
It has been described as XML lite. 
JSON Spirit is a C++ library that reads and writes JSON files or streams. 
It is written using the <a href="http://www.boost.org/libs/spirit/doc/introduction.html">Boost Spirit</a> parser generator.
If you are already using Boost then you can use JSON Spirit without any additional dependencies.

<p>The JSON Spirit source code is available as a MSVC 2005 'solution'. 
However JSON Spirit should compile and work on any platform compatible with Boost. 
JSON Spirit has been build and tested with MSVC 2005 and Bloodshed Dev-C++ version 4.9.9.2.
It has been tested with Boost versions 1.33.1, 1.34.0 and 1.34.1. 

<p>The MSVC solution consists a three projects;
the JSON Spirit library, a small program demonstrating how to use JSON Spirit, and an application containing the library's unit tests.

<h2>Using the code</h2>

<p>The MSVC library project builds an object library. 
You can link to this object library or alternatively you can add the JSON Spirit source files to your project.

<p>All JSON Spirit declarations are in the namespace <code>json_spirit</code>. 

<h3>Reading JSON</h3>

<p>You can read JSON data from a stream or a string:

<pre>
    bool read( const std::string& s, Value& value );
    bool read( std::istream& is,     Value& value );
</pre>

For example:

<pre>
    ifstream is( "json.txt" );

    Value value;

    read( is, value );
</pre>

A JSON value can hold either an JSON array, JSON object, string, integer, double, bool or null.
The interface of the JSON Spirit <code>Value</code> class is:

<pre>
    enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };

    class Value
    {
    public:

        Value();  // creates null value
        Value( const char*        value );
        Value( const std::string& value );
        Value( const Object&      value );
        Value( const Array&       value );
        Value( bool               value );
        Value( int                value );
        Value( double             value );

        bool operator==( const Value& lhs ) const;

        Value_type type() const;

        const std::string& get_str()   const;
        const Object&      get_obj()   const;
        const Array&       get_array() const;
        bool               get_bool()  const;
        int                get_int()   const;
        double             get_real()  const;

        Object& get_obj();
        Array&  get_array();

        static const Value null;
	
    private:
	
        ...
		
    };
</pre>

<p>You obtain the value's type by calling <code>Value::type()</code>. 
You can then call the appropriate getter function.
Generally you will know a file's format so you will know what type the values in a file should have.

<p>A <code>Value</code> read from a file or stream will contain an <code>Array</code> or an <code>Object</code>. 
An <code>Array</code> is a <code>std::vector</code> of values, and an <code>Object</code> is a <code>std::vector</code> of JSON pairs.

<pre>
    typedef std::vector< Pair > Object;
    typedef std::vector< Value > Array;
</pre>

A <code>Pair</code> is a struct that holds an <code>std::string</code> and a <code>Value</code>.

<pre>
    struct Pair
    {
        Pair( const std::string& name, const Value& value );

        bool operator==( const Pair& lhs ) const;

        std::string name_;
        Value value_;
    };
</pre>

<p>As JSON arrays and object can themselves contain other arrays or objects a hierarchical tree structure is be formed.

<h3>Writing JSON</h3>

<p>To output JSON first create a <code>Value</code> object containing your data.
Then write the created <code>Value</code> to a stream or a string. 
There are two versions of each function. One that outputs the JSON data without any whitespace.
The other formats the data adding whitespace and line breaks,

<pre>
    void        write          ( const Value& value, std::ostream& os );
    void        write_formatted( const Value& value, std::ostream& os );
    std::string write          ( const Value& value );
    std::string write_formatted( const Value& value );
</pre>

The following example shows how to create a small JSON file containing an object with three members:

<pre>
    Object addr_obj;

    addr_obj.push_back( Pair( "house_number", 42 ) );
    addr_obj.push_back( Pair( "road",         "East Street" ) );
    addr_obj.push_back( Pair( "town",         "Newtown" ) );

    ofstream os( "address.txt" );

    write_formatted( addr_obj, os );

    os.close();
</pre>

<p>The object <code>addr_obj</code> is automatically converted to a <code>Value</code> as it is passed to <code>write_formatted</code>. 
<p>The file address.txt will contain:

<pre>
{
    "house_number" : 42,
    "road" : "East Street",
    "town" : "Newtown"
}
</pre>


<h3>Include files</h3>

<p>To read JSON files you will need to include <code>json_spirit_reader.h</code> and <code>json_spirit_value.h</code>. 
To generate JSON files you will need to include <code>json_spirit_writer.h</code> and <code>json_spirit_value.h</code>. 
Alternatively you can include <code>json_spirit.h</code>. 
This include all three of the above.
 
<h2>Points of Interest</h2>

<p>About a month ago I decided to use JSON for a hobby project. 
The <a href="http://www.json.org">JSON</a> website listed three C++ implementations.
After a cursory look at each I discovered that the one I preferred, <a href="http://www.gnu.org/software/flex/">Jaula</a>, used <a href="http://morongo.homelinux.net/jaula/">Flex</a> to do its lexical analysis.
I would prefer my project not to depend on too may external libraries so, as I was already using Boost, I thought I would write my own JSON parser using Boost Spirit.

<p>Since then another C++ parser implementation has appear on the JSON website. The new one, <a href="http://ddsbench.svn.sourceforge.net/viewvc/ddsbench/trunk/jost/>JOST</a>, also uses Boost Spirit!
There are however considerable differences between JSON Spirit and JOST in both design and implementation.

<h2>History</h2>

<p> 10th August 2007, Version 1.0, 

<!-------------------------------    That's it!   --------------------------->
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior) Spirent Communications Plc
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions