[Boost] JSON

Alexandria·2024년 3월 4일
0

Boost

목록 보기
5/5
post-thumbnail

1. 파싱

문자열 형태의 JSON 데이터를 stringstream에 넣은 뒤

read_json을 통해 파싱이 된다.

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
}

파싱이 되었다면 JSON 를 통해 을 얻을 수 있다.

두번째 인자는 키가 존재하지 않을 시 반환될 값이다.

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
    std::cout << pt.get<std::string>("FIRST",   "") << std::endl;
    std::cout << pt.get<std::string>("SECOND",  "") << std::endl;
    std::cout << pt.get<std::string>("THIRD",   "NOT EXIST") << std::endl;
}

혹은 키의 존재를 iterator를 통해 확인 후 값에 접근할 수 있는 방법이 있다.

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
    boost::property_tree::ptree::assoc_iterator fit = pt.find("SECOND");
    if (pt.not_found() != fit) std::cout << "Value : " << (*fit).second.data() << std::endl;
}

키의 값이 단일 값이 아닌 배열이나 또 다른 JSON이라면 get_child를 호출한다.

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
    // 배열 형
    boost::property_tree::ptree& pt_array = pt.get_child("ARRAY");
    for (boost::property_tree::ptree::value_type &element : pt_array) {
        std::cout << element.second.get<unsigned int>("") << std::endl;
    }
    
    // JSON 형
    boost::property_tree::ptree& pt_json = pt.get_child("X");
    std::cout << pt_json.get<char>("Y",  "None") << std::endl;
    std::cout << pt_json.get<char>("YY", "None") << std::endl;
    std::cout << std::endl;
}

키의 이름을 통해서 접근하는 방법말고 반복문을 통해서 모든 키와 값에 접근해본다.

이때, 특정 키의 값(v.second.data())이 비어있다면 배열 혹은 JSON일 수 있으므로

다시 반복문을 통해 호출할 수 있다.

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt) {
        std::cout << v.first << " : " << v.second.data();
        if (v.second.data().empty()) {
            BOOST_FOREACH(boost::property_tree::ptree::value_type &vv, v.second) {
                if (!vv.first.empty()) std::cout << vv.first << " : ";
                std::cout << vv.second.data() << " ";
            }
        }
        else {
            std::cout << v.second.data();
        }
        std::cout << std::endl;
    }
}

전체 코드는 다음과 같다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

void parse(const char *data)
{
    std::stringstream ss;
    boost::property_tree::ptree pt;

    ss << data;
    boost::property_tree::read_json(ss, pt);
    std::cout << pt.get<std::string>("FIRST",   "") << std::endl;
    std::cout << pt.get<std::string>("SECOND",  "") << std::endl;
    std::cout << pt.get<std::string>("THIRD",   "NOT EXIST") << std::endl;

    boost::property_tree::ptree& pt_array = pt.get_child("ARRAY");
    for (boost::property_tree::ptree::value_type &element : pt_array) {
        std::cout << element.second.get<unsigned int>("") << std::endl;
    }
    
    boost::property_tree::ptree& pt_json = pt.get_child("X");
    std::cout << pt_json.get<char>("Y",  "None") << std::endl;
    std::cout << pt_json.get<char>("YY", "None") << std::endl;
    std::cout << std::endl;

    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt) {
        std::cout << v.first << " : " << v.second.data();
        if (v.second.data().empty()) {
            BOOST_FOREACH(boost::property_tree::ptree::value_type &vv, v.second) {
                if (!vv.first.empty()) std::cout << vv.first << " : ";
                std::cout << vv.second.data() << " ";
            }
        }
        else {
            std::cout << v.second.data();
        }
        std::cout << std::endl;
    }
}

int main(void)
{
    const char *data = "{\"FIRST\":\"HELLO WORLD\",\"SECOND\":\"JSON\",\"ARRAY\":[\"1\",\"2\"],\"X\":{\"Y\":\"Z\"}}";
    parse(data);
}

2. JSON 생성

다음과 같은 JSON 데이터를 생성한다고 해보자.

{
    "FIRST": "HELLO WORLD",
    "SECOND": "JSON",
    "ARRAY": [
        "1",
        "2"
    ],
    "X": {
        "Y": "Z"
    }
}

FIRST라는 키에 HELLO WORLD가 있어야 하며, SECOND라는 키의 값은 JSON이다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>


void create() {
    boost::property_tree::ptree pt, pt_children, pt_child1, pt_child2, pt_child3;
    pt.put("FIRST", "HELLO WORLD");
    pt.put("SECOND", "JSON");
}

ARRAY라는 키의 값은 1과 2를 가지는 배열 형태이다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

void create() {
    ...

    pt_child1.put("", 1);
    pt_child2.put("", 2);
    pt_children.push_back(std::make_pair("", pt_child1));
    pt_children.push_back(std::make_pair("", pt_child2));
    pt.add_child("ARRAY", pt_children);
}

X라는 키의 값은 또 다른 JSON이며 키는 Y이고 값은 Z이다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

void create() {
    ...

    pt_child3.put("Y", "Z");
    pt.add_child("X", pt_child3);
}

이제 JSON 데이터는 완성이 되었으며 stringstream을 통해 출력해본다.

write_json의 세번째 인자는 기본 값으로는 true이고

이는 한 줄로 표현할지 말지를 결정한다. false이면 한 줄로 표현이 된다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

void create() {
    ...

    std::stringstream ss;
    boost::property_tree::write_json(ss, pt, false);
    std::cout << ss.str() << std::endl;
    
    ss.str(std::string());

    boost::property_tree::write_json(ss, pt);
    std::cout << ss.str() << std::endl;
}

전체 코드는 다음과 같다.

#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

void create() {
    boost::property_tree::ptree pt, pt_children, pt_child1, pt_child2, pt_child3;
    pt.put("FIRST", "HELLO WORLD");
    pt.put("SECOND", "JSON");

    pt_child1.put("", 1);
    pt_child2.put("", 2);
    pt_children.push_back(std::make_pair("", pt_child1));
    pt_children.push_back(std::make_pair("", pt_child2));
    pt.add_child("ARRAY", pt_children);

    pt_child3.put("Y", "Z");
    pt.add_child("X", pt_child3);

    std::stringstream ss;
    boost::property_tree::write_json(ss, pt, false);
    std::cout << ss.str() << std::endl;
    
    ss.str(std::string());

    boost::property_tree::write_json(ss, pt);
    std::cout << ss.str() << std::endl;
}

int main(void) {
    create();
}
profile
IT 도서관

0개의 댓글

관련 채용 정보