需求:
在對mongodb中的欄位值進行解析的時候發現,因為這個值是json字串,需要對其進行還原序列化。
解決方案:
首先想到了到http://www.json.org/json-zh.html網站去找相應的C++庫,試了一下jsoncpp和JSON Spirit,因為是用scons來構建了,裝了一下,編譯以後玩不起來,放棄了。再試JSON Spirit,(http://www.codeproject.com/Articles/20027/JSON-Spirit-A-C-JSON-Parser-Generator-Implemented), 這東東不錯,好像是依賴於Boost Spirit的,這個我也裝了,安裝過程還是滿方便的,因為我的C++項目都是用CMake的,這個也是用它的,所以編譯安裝沒有遇到什麼問題。下面給出一個相應的例子:
#include <json_spirit.h>const std::string test ="{"" \"text\": \"Home-plate umpire Crawford gets stung http://tinyurl.com/27ujc86\","" \"favorited\": false,"" \"source\": \"<a href=\\\"http://apiwiki.twitter.com/\\\" rel=\\\"nofollow\\\">API</a>\","" \"user\": {"" \"name\": \"Johnathan Thomas\""" }""}";int main() { namespace js = json_spirit; js::mValue top; js::read(std::string(test), top); json_spirit::mObject obj = top.get_obj(); std::cout << "--------" << std::endl; std::cout << obj["text" ].get_str() << "\n" << obj["favorited"].get_bool() << "\n" << obj["source" ].get_str() << "\n" << obj["user" ].get_obj()["name"].get_str() << "\n";}
下面想到了mongodb有自己的bson結構,這個東東和json是差不多的,在mongodb的原始碼包裡找到了json.h這個檔案看,盾到了fromjson這個方法,看來能行。呵呵
下面是我的測試代碼,因為我的value中用到了array,這裡還用到了別外一個把BSONObj轉換成Array<BSONObj>的方法。
#include <db/json.h> // load fromjson method#include <iostream>#include <string>const std::string test = "{ \"specs\" : " " [ {\"id\":\"value1\" , \"name\":\"jack\"}," " {\"id\": \"value2\", \"name\":\"jack2\"}," "{\"id\": \"value3\", \"name\":\"jack3\"}" " ]" "}";int main(){ try{ // { "specs" : [ {"id":"value1" , "name":"jack"}, {"id": "value2", "name":"jack2"},{"id": "value3", "name":"jack3"} ]} std::cout << "Test json string:" << test << std::endl; // parse json method from json.h file // throws MsgAssertionException if parsing fails. The message included with // this assertion includes a rough indication of where parsing failed. mongo::BSONObj obj = mongo::fromjson(test); mongo::BSONObj eles = obj["specs"].Obj(); // get array obj /** add all values of the object to the specified vector. If type mismatches, exception. this is most useful when the BSONObj is an array, but can be used with non-arrays too in theory. example: bo sub = y["subobj"].Obj(); vector<int> myints; sub.Vals(myints); */ vector<mongo::BSONObj> specs; eles.Vals(specs); // print values for(int i = 0; i < 3; ++i) std::cout << specs.at(i)["id"].String() << ":" << specs.at(i)["name"].String()<< endl; } catch(const mongo::MsgAssertionException& e) { std::cout << "parse exception " << e.what() << endl; }}
運行結果:
gxl@gxl-desktop:~/Test_place$ g++ sample.cpp -o sample -I/usr/local/include/mongo/ -lmongoclientgxl@gxl-desktop:~/Test_place$ ./sample Test json string:{ "specs" : [ {"id":"value1" , "name":"jack"}, {"id": "value2", "name":"jack2"},{"id": "value3", "name":"jack3"} ]}value1:jackvalue2:jack2value3:jack3