property_tree Sınıfı
Giriş
Şu satırı dahil ederiz.
Alanların tip bilgisi kaybolur. Açıklaması şöyle
add_child metodu - dizi ekler
Açıklaması şöyle
Diziye yeni nesne ekler. Şöyle yaparız.
Şöyle yaparız.
json nesnesine ismi olan bir alan ve değer ekler. Alan yeni ise altta put_child metodunu çağırır. put_child + ptree olarak kullanmaktan daha kolay.
Şöyle yaparız.
json nesnesine ismi olan bir nesne ekler. push_back + std::make_pair kullanmaktan daha kolay.
Şöyle yaparız.
read_json metodu
Şu satırır dahil ederiz.
Commentler
Olmasa daha iyi. Açıklaması şöyle
Şöyle yaparız.
Şöyle yaparız.
Daha özel bir exception yakalamak istersek ptree_error'dan kalıtan json_parser_error yakalanabilir. Şöyle yaparız.
Şöyle yaparız. Bazen include dosyalarını diğer tüm include'ların altına yazmak gerekiyor.
json çıktısının daha güzel ve okunaklı olması için şöyle yaparız.
Giriş
Şu satırı dahil ederiz.
#include <boost/property_tree/ptree.hpp>
Kolay kullanmak için şu satırı dahil ederiz.using boost::property_tree::ptree;
Bu sınıf tam anlamıyla bir json kütüphanesi değil. Örneğin herşeyi sadece string olarak yazıyor. Açıklaması şöyleBoost does not have an XML library.Boost does not have a JSON library.Boost has a Property Tree library. It deals with Property Trees. Not JSON, XML or whatever else.
Eğer tam bir json kütüphanesi gerekiyorsa nlohmann veya RapidJSON kullanılabilir. Açıklaması şöyle[...] JSON values are mapped to nodes containing the value. However, all type information is lost; numbers, as well as the literals "null", "true" and "false" are simply mapped to their string form. Property tree nodes containing both child nodes and data cannot be mapped.
Because of these limitations, be smart and choose for a JSON library to build your requirements upon.
Açıklaması şöyle
Add the node at the given path. Create any missing parents. If there already is a node at the path, add another one with the same key.Dizi olarak eklemesinin açıklaması ise şöyle. put() metodu path var ise mevcut nesneyi yeni nesne ile değiştirir. add_child ise diziye ekler.
The add_child member function allows you to insert one property_tree into the DOM of another as a child node. If the key path you provide already exists a duplicate key will be added and the child will be inserted there instead.Bir başka açıklama şöyle
The difference between put_child() and add_child() is that put_child() accesses a key if that key already exists,while add_child() always inserts a new key into the tree.İsmi olan bir dizi ekler. Çıktı olarak şunu alırız.
{"Some Key":[{...},{...},{...},...,{...}]}
Bu metod ile ismi olmayan bir dizi eklemek mümkün değil. Yani şu çıktıyı alamayız.
Şöyle yaparız.
Şöyle yaparız.
get, get (default-value version), ve get_optional bir düğüme erişmek için kullanılabilir.
Eğer belirtilen yol yanlış ise exception atar. Şöyle yaparız.
get, get (default-value version), ve get_optional bir düğüme erişmek için kullanılabilir.
Elimizde şöyle bir json olsun
Düğümün ismi belirtilen alt düğümünün altındakileri verir. Yeni bir property_tree döner.
Örnek
Elimizde şöyle bir json olsun
Şöyle yaparız.
Elimizde şu json olsun
Elimizde şöyle bir json olsun
Çıktı olarak şunu alırız.
İmzası şöyle[
{
"childkeyA": "1",
"childkeyB": "2"
},
{
"childkeyA": "3",
"childkeyB": "4"
},
{
"childkeyA": "5",
"childkeyB": "6"
}
]
Açıklaması şöyleÖrnekThe property tree dataset is not typed, and does not support arrays as such. Thus, the following JSON / property tree mapping is used:
- JSON objects are mapped to nodes. Each property is a child node.
- JSON arrays are mapped to nodes. Each element is a child node with an empty name. If a node has both named and unnamed child nodes, it cannot be mapped to a JSON representation.
- JSON values are mapped to nodes containing the value. However, all type information is lost; numbers, as well as the literals "null", "true" and "false" are simply mapped to their string form.
- Property tree nodes containing both child nodes and data cannot be mapped.
JSON round-trips, except for the type information loss.
Şöyle yaparız.
boost::property_tree::propTree propTree1;
propTree2.put("l", "");
propTree2.put("m", "");
propTree1.push_back(std::make_pair("", propTree3));
propTree3.add_child("Msg", propTree1);
Çıktı olarak şunu alırız.{
"Msg": [
{
"l": "",
"m": ""
}
]
}
ÖrnekŞöyle yaparız.
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);
Çıktı olarak şunu alırız.{
"testkey": "testvalue",
"MyArray":
[
{
"childkeyA": "1",
"childkeyB": "2"
},
{
"childkeyA": "3",
"childkeyB": "4"
},
{
"childkeyA": "5",
"childkeyB": "6"
}
]
}
get metodu - pathget, get (default-value version), ve get_optional bir düğüme erişmek için kullanılabilir.
Eğer belirtilen yol yanlış ise exception atar. Şöyle yaparız.
try
{
std::cout << "try to get not existing path" << std::endl;
std::string path = this->m_Tree.get<std::string>(PATH);
}
catch (const boost::property_tree::ptree_bad_path& e)
{
std::cout << "ptree_bad_path" << std::endl;
}
get metodu - path + default valueget, get (default-value version), ve get_optional bir düğüme erişmek için kullanılabilir.
Elimizde şöyle bir json olsun
{
"some_values":
{
"field_1": "value_1",
"field_2": true
}
}
Şöyle yaparız.pTree.get<string>("some_values.field_1", "");
pTree.get<bool>("some_values.field_2", false);
get_child metoduDüğümün ismi belirtilen alt düğümünün altındakileri verir. Yeni bir property_tree döner.
Örnek
Elimizde şöyle bir json olsun
"message":{
"message_id":123,
"from":{
"id":12345,
"first_name":"name",
"username":"username"
},
"chat":{
"id":12345,
"first_name":"name",
"username":"username",
"type":"private"
},
"date":1478144459,
"text":"this is \ud83d\udca9 a sentence"
}
text alanını değerine erişmek için şöyle yaparız.for (const property_tree::ptree::value_type& child, root.get_child("result"))
{
std::string message = child.second.get<std::string>("message.text");
...
}
ÖrnekŞöyle yaparız.
std::istringstream iss(R"({
"topology_1": {
"clnt_id": "aldgdsgsd",
"sensors": {
"num_sensors": "6",
"sensor_1": {
"time_interval": "5#15",
"min_bound": "",
"max_bound": "54",
"anomaly": "2%",
"anomaly_window": "70",
"jump": "10",
"topic": "sense/thubrahali/temp",
"qos": "1"
}
}
}
})");
ptree document;
read_json(iss, document);
// and back to string
std::string topology_1 = as_json_string(document.get_child("topology_1"));
Çıktı olarak şunu alırız.{
"clnt_id": "aldgdsgsd",
"sensors": {
"num_sensors": "6",
"sensor_1": {
"time_interval": "5#15",
"min_bound": "",
"max_bound": "54",
"anomaly": "2%",
"anomaly_window": "70",
"jump": "10",
"topic": "sense\/thubrahali\/temp",
"qos": "1"
}
}
}
ÖrnekElimizde şu json olsun
{
"nodes":{
"192.168.1.1": {
"type":"type1",
"info":"info1",
"error":"error1"
},
"192.168.1.2":{
"type":"type2",
"info":"info2",
"error":"error2"
},
"test":{
"type":"type2",
"info":"info2",
"error":"error2"
}
}
}
IP düğümlerini dolaşmak için şöyle yaparız.BOOST_FOREACH(ptree::value_type &v, pt.get_child("nodes"))
{
std::string key_ = v.first.data();
std::string val_ = v.second.data();
...
}
Örnek - get_child ile array dolaşmakElimizde şöyle bir json olsun
{"json": "a_string", "data": [0,1,2,3,4]}
data'nın ilk elemanına erişmek için şöyle yaparız.string str = ...;
stringstream ss (str);
ptree root;
read_json(ss,root);
int first_value = root.get_child("data").begin()->second.get_value<int>();
Örnek
- get_child ile array dolaşmakBelirtilen indeksteki array elemanına erişmek için şöyle yaparız. element_at index'in taşıp taşmadığını kontrol etmez. element_at_checked eder.
template <typename T = std::string>
T element_at(ptree const& pt, std::string name, size_t n) {
return std::next(pt.get_child(name).find(""), n)->second.get_value<T>();
}
template <typename T = std::string>
T element_at_checked(ptree const& pt, std::string name, size_t n) {
auto r = pt.get_child(name).equal_range("");
for (; r.first != r.second && n; --n) ++r.first;
if (n || r.first==r.second)
throw std::range_error("index out of bounds");
return r.first->second.get_value<T>();
}
Şöyle yaparız.
ptree pt;
{
std::istringstream iss("{\"a\":[1, 2, 3, 4, 5, 6]}");
read_json(iss, pt);
}
// get the 4th element:
std::cout << element_at_checked(pt, "a", 3) << "\n";
// get it as int
std::cout << element_at_checked<int>(pt, "a", 3) << "\n";
// get non-existent array:
try {
std::cout << element_at_checked<int>(pt, "b", 0) << "\n";
} catch(std::exception const& e) {
std::cout << e.what() << "\n";
}
try {
std::cout << element_at_checked<int>(pt, "a", 6) << "\n";
} catch(std::exception const& e) {
std::cout << e.what() << "\n";
}
Örnek -
get_child ile array dolaşmakElimizde şöyle bir json olsun
{
"weather": [
{
"id": "701",
"main": "Mist",
"description": "brume",
"icon": "50n"
},
{
"id": "502",
"main": "Sun",
"description": "soleil",
"icon": "50b"
}
]
}
Şöyle yaparız.
for (auto it: root.get_child("weather")) {
cout << it.second.get_child("description").data() << endl;
}
brume
soleil
get_child_optional metodu
Düğümler arasında ayraç olarak "/" kullanmak için şöyle yaparız.boost::optional< ptree& > child = pt.get_child_optional(
ptree::path_type("nodes/192.168.1.1", '/'));
get_optional metodu
get, get (default-value version), ve get_optional bir düğüme erişmek için kullanılabilir.
Açıklaması şöyle.
Açıklaması şöyle.
Three Ways of Getting Data
There are three versions of get: get, get (default-value version), and get_optional, which differ by failure handling strategy. All versions take path specifier, which determines in which key to search for a value. It can be a single key, or a path to key, where path elements are separated with a special character (a '.' if not specified differently). For example debug.logging.errorlevel might be a valid path with dot as a separator.
Örnek
Şöyle yaparız.
Şöyle yaparız.
ptree pt;
/* ... */
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");
Örnek
Şöyle yaparız.
Elimizde şöyle bir xml olsun ve biz derindeki bir düğümü okumak isteyelim.
Şöyle yaparız.
boost::property_tree::ptree tree;
// if path doesn't exist, put value
if (!tree.get_optional<bool>("my.path.to.thing").is_initialized())
{
tree.put("my.path.to.thing", true);
}
ÖrnekElimizde şöyle bir xml olsun ve biz derindeki bir düğümü okumak isteyelim.
boost::property_tree::ptree pt = ...;
...
std::string my_value;
if (read_from(my_value, pt, "my_value")) {
std::cout << "Retrieved value: " << my_value << "\n";
}
Şöyle yaparız.//template <typename Ptree>
bool read_from(std::string& into, Ptree const& pt, std::string const& target) {
if (auto v = pt.get_optional<std::string>(target)) {
into = *v;
return true;
}
for (auto& child : pt) {
if (read_from(into, child.second, target)) return true;
}
return false;
}
push_back metoduiterator push_back(const value_type &);
Bu kütüphane diziler ile iyi çalışmıyor. İsmi olmayan bir dizi çıktısı alamıyoruz.[{...},{...},{...},...,{...}]
Açıklaması şöyle.ÖrnekThe property tree dataset is not typed, and does not support arrays as such. Thus, the following JSON / property tree mapping is used:
- JSON objects are mapped to nodes. Each property is a child node.
- JSON arrays are mapped to nodes. Each element is a child node with an empty name. If a node has both named and unnamed child nodes, it cannot be mapped to a JSON representation.
- JSON values are mapped to nodes containing the value. However, all type information is lost; numbers, as well as the literals "null", "true" and "false" are simply mapped to their string form.
- Property tree nodes containing both child nodes and data cannot be mapped.
- JSON round-trips, except for the type information loss.
Diziye yeni nesne ekler. Şöyle yaparız.
ptree arr;
basic_ptree<std::string, std::string> elem1, elem2;
elem1.put<std::string>("key1", "pol");
elem1.put<std::string>("key2", "active");
elem2.put<std::string>("key1", "eng");
elem2.put<std::string>("key2", "available");
arr.push_back (std::make_pair("", elem1));
arr.push_back (std::make_pair("", elem2));
Bu dizi yazdırılırsa şunu alırız.[
{
"key1": "pol",
"key2": "active"
},
{
"key1": "eng",
"key2": "available"
}
]
ÖrnekŞöyle yaparız.
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
int main()
{
boost::property_tree::ptree pt;
std::vector<double> Vec={1.1,2.2,3.3};
for(double x:Vec)
{
std::string x_string=std::to_string(x);
pt.push_back(
std::make_pair("",
boost::property_tree::ptree(x_string)) );
}
boost::property_tree::json_parser::write_json(std::cout, pt);
std::cout<<std::endl;
return 0;
}
Çıktı olarak şunu alırız. Çıktı olarak [] almıyoruz çünkü nesnemiz 0. seviye.{
"": "1.100000",
"": "2.200000",
"": "3.300000"
}
put metodu - alan + değer eklerjson nesnesine ismi olan bir alan ve değer ekler. Alan yeni ise altta put_child metodunu çağırır. put_child + ptree olarak kullanmaktan daha kolay.
Şöyle yaparız.
basic_ptree<std::string, std::string> elem;
elem.put<std::string>("key1", "pol");
elem.put<std::string>("key2
", "active");
Bu nesne yazdırılırsa şunu alırız.{
"key1": "pol",
"key2": "active"
}
İsim alanı boş verilebilir. Şöyle yaparız.ptree elem;
elem.put("", 1);
Bu nesne yazdırılırsa şunu alırız.{
"1"
}
put_child metodu - dizi eklerjson nesnesine ismi olan bir nesne ekler. push_back + std::make_pair kullanmaktan daha kolay.
Şöyle yaparız.
ptree arr;
...
ptree root;
root.put_child ("path1",arr);
arr bir dizi olduğu için çıktı olarak şunu alırız.{
"path1": [
{
"key1": "pol",
"key2": "active"
},
{
"key1": "eng",
"key2": "available"
}
]
}
Free Style Metodlarread_json metodu
Şu satırır dahil ederiz.
#include<boost/property_tree/json_parser.hpp>
"boost::property_tree::json_parser" isim alanı altındaki read_json metodunu kullanırız.Commentler
Olmasa daha iyi. Açıklaması şöyle
The official JSON standard does not define a syntax for comments.Örnek
Support for comments is implemented (or not) on a per-parser basis. It was probably something that Boost once supported for convenience but later removed for compliance (I'm speculating, as I don't use Boost myself).
If Boost no longer supports comments, you will have to strip them out before parsing.
Şöyle yaparız.
std::stringstream ss = ...;
ptree pt;
try {
json_parser::read_json<ptree> (ss, pt);
} catch (boost::property_tree::ptree_error &e) {
...
} catch (std::exception& e) {
...
}
Örnek - localeŞöyle yaparız.
boost::locale::generator gen;
auto CN = gen.generate("zh_CN.GBK");
Daha sonra stream'e geçerek şöyle yaparız.std::ifstream ifs(filename, std::ios::binary);
ifs.imbue(CN);
boost::property_tree::ptree pt;
read_json(ifs, pt);
Örnek - exceptionDaha özel bir exception yakalamak istersek ptree_error'dan kalıtan json_parser_error yakalanabilir. Şöyle yaparız.
try
{
// Trying to load the file
}
catch (const boost::property_tree::json_parser_error& e)
{
//Here what i do if i cant find the file
}
write_json metoduŞöyle yaparız. Bazen include dosyalarını diğer tüm include'ların altına yazmak gerekiyor.
ptree root;
...
std::stringstream ss;
json_parser::write_json (ss, root);
Daha kolay kullanım için şöyle yaparız.std::string as_json_string(ptree const& pt) {
std::ostringstream oss;
write_json(oss, pt);
return oss.str();
}
write_json - prettyjson çıktısının daha güzel ve okunaklı olması için şöyle yaparız.
write_json(oss, pt, true);
Hiç yorum yok:
Yorum Gönder