さてこれまでブラウザ上でJSONデータの扱いを調べてきましたが、これらは入力データの編集用と思って調べてきました。こっからが本題のc++によるJSONデータの扱いです。
もともと、本職はc++プログラムがほとんどなんで、いつも入出力のGUIに悩まされていました。それをCouchDBで楽したいというところで、色々調べていましたがだいたい目処がついてきたので、さてそれをc++プログラムでどうやってハンドリングしたらいいのか?というところまできました。
c++でJSONのパーサはいくつか見つかりましたが、picojsonがヘッダファイル一つというシンプルさでなかなか秀逸です。早速これを試してみました。
まず試験データとしてのJSONファイル(test3.json)です。
{"message":"success",
"number":[1, 2],
"person":{"name":"hoge", "age":38},
"follow":[
{"name":"hoge", "age":38},
{"name":"huga", "age":42}
],
"returnCode":0}
わざと複雑な階層構造を持たせています。このファイル名を引数として動くサンプルが以下です。
#include
#include
実行すると以下の様な出力をだしてきます。
---- dump input ----
{"follow":[{"age":38,"name":"hoge"},{"age":42,"name":"huga"}],"message":"success","nu\
mber":[1,2],"person":{"age":38,"name":"hoge"},"returnCode":0}
---- analyzing input ----
input is an object
follow [{"age":38,"name":"hoge"},{"age":42,"name":"huga"}]
message "success"
number [1,2]
person {"age":38,"name":"hoge"}
returnCode 0
success
follow [{"age":38,"name":"hoge"},{"age":42,"name":"huga"}]
message "fail"
number [1,2]
person {"age":38,"name":"hoge"}
piyopiyo 10
returnCode 0
hoge 38
huga 42
{"follow":[{"age":38,"name":"hoge"},{"age":42,"name":"huga"}],"message":"fail","numbe\
r":[1,2],"person":{"age":42,"name":"huga"},"piyopiyo":10,"returnCode":0}
うまく動いていますね。階層構造の扱いも、値の変更も思い通りになります。
ちょっと面倒くさいのが、いちいちpicojson::value形式で読みこんだ後、データの操作のためにpicojson::object形式にしないといけないこと。JavaScriptでも同じような考え方でしたが何でですかね?picojsonの実装はヘッダファイル一つなので、少し読んでみると、picojson::valueではvector形式で読み込んでいるようですが、すぐにmap形式にしてしまいます。確かにこれならアクセスするのが簡単で、処理速度も早いんですがデータ項目の順番がkeyでソートされてしまい順番が変わってしまいます。JSONとしては問題ないんですが、デバッグ時に少し悩みそうです。
後、このサンプルではparse()関数を使っていますが、picojson::valueは、>>を使って直接読み込むことができます。わざわざサンプル用に、stringでファイルを読み込み、parse()関数を使うように変更しました。こっちの方がエラーの扱いがわかりやすいからなんですがね。
picojsonなかなかいいんですが、一つ難点を言えば、c++のtemplate機能を使い倒しているため、エラーが出てくると、わけのわからないエラーメッセージを出してくるのがつらいです。c++の機能なんで、しかたないんですが。
0 件のコメント:
コメントを投稿