Boost logo

Boost Users :

Subject: Re: [Boost-users] [property_tree] Parsing JSON
From: Bryce Lelbach (admin_at_[hidden])
Date: 2011-01-05 10:04:00


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I have finished a prototype of this. I haven't tested accessing objects by
zero index yet, but I suspect it will work fine.

I made an example for you, that takes this as an input:

http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/wa/wsSearch?term=sudoku&entity=software&limit=1

and accesses the results[0].artworkUrl100.

Here it is:

#include <boost/spirit/home/prana/input/parse_json.hpp>
#include <boost/spirit/home/prana/output/generate_json.hpp>
#include <boost/spirit/home/prana/dsir/json/ir.hpp>
#include <boost/spirit/home/prana/support/file_io.hpp>

int main (void) {
  using boost::spirit::utree;
  using boost::spirit::prana::ignore_utf8_bom;
  using boost::spirit::prana::parse_exception;
  using boost::spirit::prana::json_ir;
  using boost::spirit::prana::parse_json;
  using boost::spirit::prana::generate_json;

  std::ifstream ifs("data/itunes_store.json");

  // Ignore the windows UTF8 bom, if it is there.
  ignore_utf8_bom(ifs, "data/itunes_store.json");

  // utree is the low-level, generic AST used in Prana.
  utree ast;

  // This is the low-level interface. It takes an input form (a string, stream,
  // or utree holding a string currently) as it's first parameter, and
  // produces an output, storing it in it's second parameter.
  if (!parse_json(ifs, ast))
    throw parse_exception();

  // json_ir is a DSIR - a domain specific intermediate representation. It's a
  // shallow view into the underlying utree AST. <-- actually, atm not a shallow
  // view, but it will be.
  json_ir ir(ast);
 
  std::cout << ir["results"][0]["artworkUrl100"] << std::endl;
  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  // This is actually a proto expression. It will never throw; if the specified
  // JSON node doesn't exist, a sentinel node is returned. The underlying utree
  // type of the sentinel node is invalid_type. Note that the type of the above
  // expression is a Proto expression wrapper, which happens to be streamable.
  // It is additionally convertible to utree and json_ir, and it also provides
  // a get member that will explicitly retrieve the underlying utree node. The
  // output from this example should be:
  // "http://a1.phobos.apple.com/us/r1000/056/Purple/e2/2b/7a/mzi.opitdvsr.tif"
}

I should advise you that my work here is mostly for my own educational benefit;
you might be better off using another JSON library. If you're interested in using
Prana, though, feel free, you'll need Boost from trunk. If you have any problems,
please let me know.

ATM, I'm pretty happy with the functionality of the JSON stuff, but not entirely
happy with the interface (json_ir should provide a constructor that takes the
input as a parameter, and calls parse_json, providing it's own utree member as
the output ast. ATM, we actually have to deep copy most of the AST, which is
expensive. Fixing this will also allow mutable operations on the JSON structure).

Note that utree is essentially a boost variant, a boost optional, a std list with
O(n) random access methods, a string, an integer, etc. However, you should also
note that the view provided by the json_ir (which is not iterable) is different
from the actual struture of the utree AST for json (which is iterable, but not
in way you'd probably want). I'm working on an iterator for json_ir, though.

Link to the example in the Prana repository:

https://github.com/brycelelbach/prana/blob/master/libs/spirit/example/prana/json_itunes_store.cpp

- --
Bryce Lelbach aka wash
boost-spirit.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAk0kiGAACgkQ9cB/V3/s9EyINwCggaVkDtKYUO3ky4BdrrgO97oQ
WCYAnRtKXuilGhyRuAtEdNsE344pFSIU
=iZhD
-----END PGP SIGNATURE-----


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net