Boost::property tree 를 이용한 json 스크립트 파싱
jjuiddong
목차 |
여러개의 속성을 가진 child 정보를 가져오는 방법
"property" : [ { "symbolname" : "CLobbyServer#1" }, { "symbolname" : "CLobbyServer#1" } ]
boost::property_tree 를 이용한 json 스크립트 파싱
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> using boost::property_tree::ptree; ptree props; boost::property_tree::read_json("filename", props); ptree &children = props.get_child("property"); BOOST_FOREACH(ptree::value_type &vt, children) { const string name = vt.second.get<string>("symbolname"); ... }
일반적인 JSon 파싱
{ "attribute1" : "100" ,"attribute2" : "0 0 100 100" ,"attribute3" : "0 0 100 100" ,"attribute4" : "200" ,"attribute5" : "5" , "attribute6" : [ { "sub-attr1" : "data1" ,"sub-attr2" : "data2" } ,{ "sub-attr1" : "data3" ,"sub-attr2" : "data4" } ] }
JSon Parsing Sample Code
bool cConfig::Read(const char *fileName) { using boost::property_tree::ptree; Clear(); try { ptree props; boost::property_tree::read_json(fileName, props); m_attribute1 = props.get<int>("attribute1", 100); m_attribute2 = props.get<string>("attribute2", "0 0 0 0"); m_attribute3 = props.get<string>("attribute3", "0 0 0 0"); m_attribute4 = props.get<int>("attribute4", 0); m_attribute5 = props.get<int>("attribute5", 5); auto &children = props.get_child("attribute6"); for (auto &vt : children) { string subAttr1 = vt.second.get<string>("sub-attr1", ""); string subAttr2 = vt.second.get<string>("sub-attr2", ""); } } catch (std::exception&e) { string err = e.what(); return false; } return true; }
다른방식의 json 파싱
json 은 key, value 값으로 구성된 스크립트지만, 다음처럼 value값이 없이도 사용할 수 있다.
"collapse" : [ "basic::s2c", "login::s2c" ]
이 스크립트의 정보를 가져오는 방법은 다음과 같다. (이 예제의 특징은 key value 만 있고, data value는 없다는 점이다.)
ptree &collapse = g_Props.get_child("collapse"); BOOST_FOREACH(auto &child, collapse) { if ("basic::s2c" == child.second.data()) return true; }
property_tree find() 로 내부 데이타 얻는법
using boost::property_tree::ptree; ptree props; boost::property_tree::read_json(fileName.c_str(), props); ptree &children = props.get_child("extract"); BOOST_FOREACH(auto &vt, children) { ptree::assoc_iterator fit = vt.second.find("field"); if (vt.second.not_found() != fit) { ptree &child_field = vt.second.get_child("field"); BOOST_FOREACH(auto &v, child_field) { Jjuiddong (토론) } } }
boost::property_tree 데이타 저장
- 이미 존재하는 scale 키 에 sens 값을 업데이트 한다.
try { // boost property tree using boost::property_tree::ptree; using std::string; ptree props; boost::property_tree::read_json(fileName, props); props.put<float>("scale", sens); boost::property_tree::write_json(fileName + "1", props); } catch (std::exception&e) { ::AfxMessageBox(CString(L"Error!!\n") + str2wstr(e.what()).c_str()); return false; }
boost::property_tree 데이타 구성
ptree pt; ptree children; ptree child1, child2, child3; child1.put("childkeyA", 1); child1.put("childkeyB", 2); child2.put("childkeyA", 3); child2.put("childkeyB", 4); child3.put("childkeyA", 5); child3.put("childkeyB", 6); children.push_back(std::make_pair("", child1)); children.push_back(std::make_pair("", child2)); children.push_back(std::make_pair("", child3)); pt.put("testkey", "testvalue"); pt.add_child("MyArray", children); write_json("test2.json", pt);
{ "testkey": "testvalue", "MyArray": [ { "childkeyA": "1", "childkeyB": "2" }, { "childkeyA": "3", "childkeyB": "4" }, { "childkeyA": "5", "childkeyB": "6" } ] }
boost::property_tree 데이타 구성2
https://stackoverflow.com/questions/2114466/creating-json-arrays-in-boost-using-property-trees
ptree pt; ptree children; ptree child1, child2, child3; child1.put("", 1); child2.put("", 2); child2.put("", 3); children.push_back(std::make_pair("", child1)); children.push_back(std::make_pair("", child2)); children.push_back(std::make_pair("", child3)); pt.add_child("MyArray", children); write_json("test2.json", pt);
{ "MyArray": [ "1", "2", "3" ] }
boost::property_tree 데이타 읽기와 저장
- Source JSon format
{ "point cloud" : [ { "name" : "name 1", "pos" : "1 2 3", "description" : "memo 1" }, { "name" : "name 2", "pos" : "1 2 3", "description" : "memo 2" } ] }
- Read JSon file c++
try { ptree props; boost::property_tree::read_json(fileName.c_str(), props); // parse point cloud ptree::assoc_iterator itor = props.find("point cloud"); if (props.not_found() != itor) { ptree &child_field = props.get_child("point cloud"); for (ptree::value_type &vt : child_field) { sPCData *pc = new sPCData; pc->name = vt.second.get<string>("name"); const string posStr = vt.second.get<string>("pos"); vector<string> toks; common::tokenizer(posStr, " ", "", toks); if (toks.size() >= 3) { pc->pos = Vector3( (float)atof(toks[0].c_str()) , (float)atof(toks[1].c_str()) , (float)atof(toks[2].c_str())); } pc->desc = vt.second.get<string>("description"); m_pcDatas.push_back(pc); } } } catch (std::exception &e) { Str128 msg; msg.Format("Read Error!!, Point Cloud Data File [ %s ]\n%s" , fileName.c_str(), e.what()); MessageBoxA(NULL, msg.c_str(), "ERROR", MB_OK); return false; }
- Write JSon file c++
try { ptree props; ptree pcs; for (auto &pc : m_pcDatas) { ptree z; z.put("name", pc->name.c_str()); Str128 text; text.Format("%f %f %f", pc->pos.x, pc->pos.y, pc->pos.z); z.put("pos", text.c_str()); z.put("description", pc->desc.c_str()); pcs.push_back(std::make_pair("", z)); } props.add_child("point cloud", pcs); boost::property_tree::write_json(fileName.c_str(), props); } catch (std::exception &e) { Str128 msg; msg.Format("Write Error!!, Point Cloud File [ %s ]\n%s" , fileName.c_str(), e.what()); MessageBoxA(NULL, msg.c_str(), "ERROR", MB_OK); return false; }