속성 트리를 사용하여 Boost에서 JSON 어레이 생성
부스트 속성 트리를 사용하여 JSON 어레이를 생성하려고 합니다.
문서에는 다음과 같이 기재되어 있습니다.JSON 어레이는 노드에 매핑되어 있습니다.각 요소는 이름이 비어 있는 하위 노드입니다."
빈 , 그에 전화하겠습니다write_json(...)
어레이를 꺼냅니다.그러나 문서에는 이름 없는 하위 노드를 만드는 방법은 나와 있지 않습니다.는 는 i i는노노 i i i i i.ptree.add_child("", value)
과 같은 결과를낳습니다: ,, 음, 다, 다, 다, 다, 니, 니, ,, ,, ,, ,.
Assertion `!p.empty() && "Empty path not allowed for put_child."' failed
이 문서에서는 이 점을 다루지 않는 것 같습니다.최소한 제가 알 수 있는 것은 아닙니다.누구 도와줄 사람?
심플한 어레이:
#include <boost/property_tree/ptree.hpp>
using boost::property_tree::ptree;
ptree pt;
ptree children;
ptree child1, child2, child3;
child1.put("", 1);
child2.put("", 2);
child3.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("test1.json", pt);
결과는 다음과 같습니다.
{
"MyArray":
[
"1",
"2",
"3"
]
}
객체 위의 배열:
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::ptree root;
boost::property_tree::ptree child1;
boost::property_tree::ptree child2;
// .. fill in children here with what you want
// ...
ptree.push_back( std::make_pair("", child1 ) );
ptree.push_back( std::make_pair("", child2 ) );
하지만 json 구문 분석과 쓰기에는 몇 가지 버그가 있습니다.그 중 몇 가지에 대해 버그 보고서를 제출했지만 응답이 없습니다.
편집: {"」로 잘못 일련화되는 것에 대한 우려에 대처하기 위해:"", ""}
이 문제는 어레이가 루트 요소인 경우에만 발생합니다.boost ptree writer는 모든 루트 요소를 개체로 취급하며 배열이나 값은 사용하지 않습니다.이는 boost/propert_tree/detail/json_parser_writer.hpp의 다음 행이 원인입니다.
else if (indent > 0 && pt.count(Str()) == pt.size())
"indent > 0 & &" 를 삭제하면 어레이를 올바르게 쓸 수 있습니다.
공간 절약이 마음에 들지 않으면 여기에 제공된 패치를 사용할 수 있습니다.
속성 트리를 사용하여 JSON 구조를 나타낼 때 유사한 문제가 발생했지만 해결하지 못했습니다.또, 이 메뉴얼에서는, 속성 트리가 타입 정보를 완전하게 서포트하고 있지 않습니다.
JSON 값은 값을 포함하는 노드에 매핑됩니다.그러나 모든 유형 정보는 손실됩니다. 숫자뿐만 아니라 리터럴 "null", "true" 및 "false"도 문자열 형식으로 매핑됩니다.
이것을 알고, 보다 완전한 JSON 실장 JSON Spirit으로 전환했습니다.이 라이브러리는 JSON 문법 구현에 Boost Spirit을 사용하며 어레이를 포함한 JSON을 완전히 지원합니다.
대체 C++ JSON 실장 사용을 권장합니다.
제 경우, 어느 정도 임의의 위치에 어레이를 추가하고 싶었기 때문에 Michael의 답변처럼 하위 트리를 만들고 어레이 요소를 채웁니다.
using boost::property_tree::ptree;
ptree targetTree;
ptree arrayChild;
ptree arrayElement;
//add array elements as desired, loop, whatever, for example
for(int i = 0; i < 3; i++)
{
arrayElement.put_value(i);
arrayChild.push_back(std::make_pair("",arrayElement))
}
자녀가 입력되면put_child()
또는add_child()
이렇게 전체 하위 트리를 대상 트리에 추가하는 기능...
targetTree.put_child(ptree::path_type("target.path.to.array"),arrayChild)
put_child 함수는 인수 경로와 트리를 사용하여 arrayChild를 타겟으로 "grapt"합니다.트리
현재boost 1.60.0
, 아직 문제가 발생.
제공:Python 3
회피책(Gist), 직후에 시스템화할 수 있습니다.boost::property_tree::write_json
.
#!/usr/bin/env python3
def lex_leaf(lf: str):
if lf.isdecimal():
return int(lf)
elif lf in ['True', 'true']:
return True
elif lf in ['False', 'false']:
return False
else:
try:
return float(lf)
except ValueError:
return lf
def lex_tree(j):
tj = type(j)
if tj == dict:
for k, v in j.items():
j[k] = lex_tree(v)
elif tj == list:
j = [lex_tree(l) for l in j]
elif tj == str:
j = lex_leaf(j)
else:
j = lex_leaf(j)
return j
def lex_file(fn: str):
import json
with open(fn, "r") as fp:
ji = json.load(fp)
jo = lex_tree(ji)
with open(fn, 'w') as fp:
json.dump(jo, fp)
if __name__ == '__main__':
import sys
lex_file(sys.argv[1])
JSON을 C++로 하려면 Boost를 사용할 필요가 없습니다.이 라이브러리를 사용하면 JSON을 STL 컨테이너처럼 작동하는 퍼스트 클래스 데이터 유형으로 가져올 수 있습니다.
// Create JSON on the fly.
json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
// Or treat is as an STL container; create an array using push_back
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);
// also use emplace_back
j.emplace_back(1.78);
// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) {
std::cout << *it << '\n';
}
공식 문서와 위의 답변에 혼란스러웠습니다.아래는 제가 이해한 내용입니다.
속성 트리는 노드로 구성됩니다.
각 노드는 다음과 같습니다.
struct ptree
{
map<key_name,value> data;
vector<pair<key_name,ptree>> children;
};
'put'으로 데이터에 'value'를 입력하려면
'push_back'을 가진 아이에게 'node'를 삽입하려면\
// Write
bt::ptree root;
bt::ptree active;
bt::ptree requested;
bt::ptree n1, n2, n3;
n1.put("name", "Mark");
n1.put("age", 20);
n1.put("job", "aaa");
n2.put("name", "Rosie");
n2.put("age", "19");
n2.put("job", "bbb");
n3.put("name", "sunwoo");
n3.put("age", "10");
n3.put("job", "ccc");
active.push_back ({ "",l1 });
active.push_back ({ "",l2 });
requested.push_back({ "",l3 });
root.push_back ({"active", active});
root.push_back ({"requested", requested});
bt::write_json("E:\\1.json", root);
// READ
bt::ptree root2;
bt::ptree active2;
bt::ptree requested2;
bt::ptree r1, r2, r3;
bt::read_json("E:\\1.json", root2);
// loop children
for (auto& [k,n] : root.get_child("active"))
{
cout << n.get<string>("name", "unknown");
cout << n.get<int> ("age" , 11);
cout << n.get<string>("job" , "man");
cout << endl << flush;
}
언급URL : https://stackoverflow.com/questions/2114466/creating-json-arrays-in-boost-using-property-trees
'programing' 카테고리의 다른 글
컨트롤러, 서비스 및 저장소 패턴에서의 DTO 사용 방법 (0) | 2023.02.25 |
---|---|
WordPress, nginx 프록시 및 서브 디렉토리: wp-login.php가 도메인으로 리다이렉트하다 (0) | 2023.02.25 |
woocommerce 속성값 목록 가져오기 (0) | 2023.02.25 |
TNS-12505: TNS: 청취자가 현재 Connect Descriptor에 지정된SID를 인식하지 않음 (0) | 2023.02.25 |
AJAX 게시 오류: 안전하지 않은 헤더 "연결" 설정을 거부했습니다. (0) | 2023.02.25 |