Follow @theboostcpplibs

Chapter 25. Boost.PropertyTree

With the class boost::property_tree::ptree , Boost.PropertyTree provides a tree structure to store key/value pairs. Tree structure means that a trunk exists with numerous branches that have numerous twigs. A file system is a good example of a tree structure. File systems have a root directory with subdirectories that themselves can have subdirectories and so on.

To use boost::property_tree::ptree , include the header file boost/property_tree/ptree.hpp . This is a master header file, so no other header files need to be included for Boost.PropertyTree.

Example 25.1 uses boost::property_tree::ptree to store a path to a directory. This is done with a call to put() . This member function expects two parameters because boost::property_tree::ptree is a tree structure that saves key/value pairs. The tree doesn’t just consist of branches and twigs, a value must be assigned to each branch and twig. In Example 25.1 the value is “ 20 files ” .

The first parameter passed to put() is more interesting. It is a path to a directory. However, it doesn’t use the backlash, which is the common path separator on Windows. It uses the dot.

You need to use the dot because it’s the separator Boost.PropertyTree expects for keys. The parameter “ C:.Windows.System ” tells pt to create a branch called C: with a branch called Windows that has another branch called System. The dot creates the nested structure of branches. If “ C:\Windows\System ” had been passed as the parameter, pt would only have one branch called C:\Windows\System.

After the call to put() , pt is accessed to read the stored value “ 20 files ” and write it to standard output. This is done by jumping from branch to branch – or directory to directory.

To access a subbranch, you call get_child() , which returns a reference to an object of the same type get_child() was called on. In Example 25.1 , this is a reference to boost::property_tree::ptree . Because every branch can have subbranches, and because there is no structural difference between higher and lower branches, the same type is used.

The third call to get_child() retrieves the boost::property_tree::ptree , which represents the directory System. get_value() is called to read the value that was stored at the beginning of the example with put() .

Please note that get_value() is a function template. You pass the type of the return value as a template parameter. That way get_value() can do an automatic type conversion.

There are two changes in Example 25.2 compared with Example 25.1 . These changes are to save paths to directories and the number of files in directories more easily. First, paths use a backslash as the separator when passed to put() . Secondly, the number of files is stored as an int .

By default, Boost.PropertyTree uses a dot as the separator for keys. If you need to use another character, such as the backslash, as the separator, you don’t pass the key as a string to put() . Instead you wrap it in an object of type boost::property_tree::ptree::path_type . The constructor of this class, which depends on boost::property_tree::ptree , takes the key as its first parameter and the separator character as its second parameter. That way, you can use a path such as C:\Windows\System, as shown in Example 25.2 , without having to replace backslashes with dots.

boost::property_tree::ptree is based on the class template boost::property_tree::basic_ptree . Because keys and values are often strings, boost::property_tree::ptree is predefined. However, you can use boost::property_tree::basic_ptree with different types for keys and values. The tree in Example 25.2 uses an int to store the number of files in a directory rather than a string.

boost::property_tree::ptree provides the member functions begin() and end() . However, boost::property_tree::ptree only lets you iterate over the branches in one level. Example 25.2 iterates over the subdirectories of C:\Windows. You can’t get an iterator to iterate over all branches in all levels.

The for loop in Example 25.2 reads the number of files in all subdirectories of C:\Windows to calculate a total. As a result, the example displays 70 . The example doesn’t access objects of type ptree directly. Instead it iterates over elements of type std::pair<std::string, ptree> . first contains the key of the current branch. That is System and Cursors in Example 25.2 . second provides access to an object of type ptree , which represents the possible subdirectories. In the example, only the values assigned to System and Cursors are read. As in Example 25.1 , the member function get_value() is called.

boost::property_tree::ptree only stores the value of the current branch, not its key. You can get the value with get_value() , but there is no member function to get the key. The key is stored in boost::property_tree::ptree one level up. This also explains why the for loop iterates over elements of type std::pair<std::string, ptree> .

Example 25.3 uses with boost::property_tree::iptree another predefined tree from Boost.PropertyTree. In general, this type behaves like boost::property_tree::ptree . The only difference is that boost::property_tree::iptree doesn’t distinguish between lower and upper case. For example, a value stored with the key C:\Windows\System can be read with c:\windows\system.

Unlike Example 25.1 , get_child() isn’t called multiple times to access subbranches. Just as put() can be used to store a value in a subbranch directly, a value from a subbranch can be read with get() . The key is defined the same way – for example using boost::property_tree::iptree::path_type .

Like get_value() , get() is a function template. You have to pass the type of the return value as a template parameter. Boost.PropertyTree does an automatic type conversion.

To convert types, Boost.PropertyTree uses translators . The library provides a few translators out of the box that are based on streams and can convert types automatically.

Example 25.3 defines the translator string_to_int_translator , which converts a value of type std::string to int . The translator is passed as an additional parameter to get() . Because the translator is just used to read, it only defines one member function, get_value() . If you want to use the translator for writing, too, then you would need to define a member function put_value() and then pass the translator as an additional parameter to put() .

get_value() returns a value of the type that is used in pt . However, because a type conversion doesn’t always succeed, boost::optional is used. If a value is stored in Example 25.3 that can’t be converted to an int with std::strtol() , an empty object of type boost::optional will be returned.

Please note that a translator must also define the two types internal_type and external_type . If you need to convert types when storing data, define put_value() similar to get_value() .

If you modify Example 25.3 to store the value “ 20 ” instead of value “ 20 files ” , get_value() can be called without passing a translator. The translators provided by Boost.PropertyTree can convert from std::string to int . However, the type conversion only succeeds when the entire string can be converted. The string must not contain any letters. Because std::strtol() can do a type conversion as long as the string starts with digits, the more liberal translator string_to_int_translator is used in Example 25.3 .

You can call the member function get_optional() if you want to read the value of a key, but you aren’t sure if the key exists. get_optional() returns the value in an object of type boost::optional . The object is empty if the key wasn’t found. Otherwise, get_optional() works the same as get() .

It might seem like put_child() and add_child() are the same as put() . The difference is that put() creates only a key/value pair while put_child() and add_child() insert an entire subtree. Note that an object of type boost::property_tree::ptree is passed as the second parameter to put_child() and add_child() .

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. That’s why the tree in Example 25.4 has two keys called “ D:.Program Files ” . Depending on the use case, this can be confusing. If a tree represents a file system, there shouldn’t be two identical paths. You have to avoid inserting identical keys if you don’t want duplicates in a tree.

Example 25.4 displays the value of the keys below “ D: ” in the for loop. The example writes 50 files and 60 files to standard output, which proves there are two identical keys called “ D:.Program Files ” .

The last member function introduced in Example 25.4 is get_child_optional() . This function is used like get_child() . get_child_optional() returns an object of type boost::optional . You call boost::optional if you aren’t sure whether a key exists.

Boost.PropertyTree does more than just provide structures to manage data in memory. As can be seen in Example 25.5 , the library also provides functions to save a boost::property_tree::ptree in a file and load it from a file.

The header file boost/property_tree/json_parser.hpp provides access to the functions boost::property_tree::json_parser::write_json() and boost::property_tree::json_parser::read_json() . These functions make it possible to save and load a boost::property_tree::ptree serialized in the JSON format. That way you can support configuration files in the JSON format.

If you want to call functions that store a boost::property_tree::ptree in a file or load it from a file, you must include header files such as boost/property_tree/json_parser.hpp . It isn’t sufficient to only include boost/property_tree/ptree.hpp .

In addition to the functions boost::property_tree::json_parser::write_json() and boost::property_tree::json_parser::read_json() , Boost.PropertyTree provides functions for additional data formats. You use boost::property_tree::ini_parser::write_ini() and boost::property_tree::ini_parser::read_ini() from boost/property_tree/ini_parser.hpp to support INI-files. With boost::property_tree::xml_parser::write_xml() and boost::property_tree::xml_parser::read_xml() from boost/property_tree/xml_parser.hpp , data can be loaded and stored in XML format. With boost::property_tree::info_parser::write_info() and boost::property_tree::info_parser::read_info() from boost/property_tree/info_parser.hpp , you can access another format that was developed and optimized to serialize trees from Boost.PropertyTree.

None of the supported formats guarantees that a boost::property_tree::ptree will look the same after it has been saved and reloaded. For example, the JSON format can lose type information because boost::property_tree::ptree can’t distinguish between true and “ true ” . The type is always the same. Even if the various functions make it easy to save and load a boost::property_tree::ptree , don’t forget that Boost.PropertyTree doesn’t support the formats completely. The main focus of the library is on the structure boost::property_tree::ptree and not on supporting various data formats.

Create a program that loads this JSON -file and writes the names of all animals to standard output. If “ all ” is set to true the program should not only write the names but all properties of all animals to standard output:

How to use boost::property_tree to load and write JSON

Property Tree is a sublibrary of boost that allow you handling tree of property . It can be used to represent XML, JSON, INI files, file paths, etc. In our case, we will be interested in loading and writing JSON, to provide an interface with other applications.

Our example case will be the following json file :

Reading data

Let’s have a look at how we can load those data into our c++ application.

First, we need to include the libraries and load the file.

Now, we have a populated property tree thatis waiting from us to look at him. Notice that you can also read from a stream, for example pt::read_json(std::cin, root) {.cpp} is also allowed.

If your json file is illformed, you will be granted by a pt::json_parser::json_parser_error .

Loading some values

We can access a value from the root by giving it’s path to the get method.

If the field your are looking to doesn’t exists, the get() method will throw a pt::ptree_bad_path exception, so that you can recorver from incomplete json files. Notice you can set a default value as second argument, or use get_optional<T>() wich return a boost::optional<T> .

Notice the getter doesn’t care about the type of the input in the json file, but only rely on the ability to convert the string to the type you are asking.

Browsing lists

So now, we would like to read a list of objects (in our cases, a list of animals).

We can handle it with a simple for loop, using an iterator. In c++11 , it become :

Since animal.second is a ptree , we can also call call get() or get_child() in the case our node wasn’t just a string.

A bit more complexe example is given by a list of values. Each element of the list is actualy a std::pair("", value) (where value is a ptree ). It doesnt means that reading it is harder.

In the case the values arent string, we can just call fruit.second.get_value<T>() in place of fruit.second.data() .

Deeper : matrices

There is nothing now to enable reading of matrices, but it’s a good way to check that you anderstood the reading of list. But enought talking, let’s have a look at the code.

You can now read any kind of JSON tree. The next step is being able to read them.

Writing JSON

Let’s say that now, we wan’t to produce this tree from our application’s data. To do that, all we have to do is build a ptree containing our data.

We start with an empty tree :

Puting values in a tree can be acomplished with the put() method.

As you can see, very boring.

Add a list of objects

No big deel here, although we now use add_child() to put our animal node at the root.

Add many nodes with the same name

Now start the tricky tricks. If you want to add more than one time a node named fish , you can’t call the put() method. The call node.put("name", value) will replace the existing node named name . But you can do it by manually pushing your nodes, as demonstrated bellow.

Add a list of values

If you remember, list are mades of nodes with empty name. Se we have to build node with empty names, and then use the push_back() once again to add all those unnamed childs.

Add a matrix

We already have all the tools needed to export our matrix. But let’s demonstrate how to do it.

You can download a C++ example and the input JSON file for experimenting. Compile it with clang++ -std=c++11 example.cpp -o example .

Some links related :

  • The official documentation
  • A post on stack overflow

Rem : At the time of writing, the boost::property_tree library doesn’t output typed value. But we can expect that it will be corrected soon.

Related Posts

List zipper applied to ios swift 24 may 2019, what is wrong with the object paradigm 17 feb 2017, an alternative error handling strategy for c++ 27 aug 2013.

  • Marko Editor

How to store anything in Boost PropertyTree

One of the fundamental data structures in information processing is the tree, to model hierarchical data. Although we have many standardized containers in C++, a tree structure is still missing. Of course, there are several different libraries which provide this feature in different facets. For my current work I am using Boost PropertyTree and in this article I want to describe a small enhancement to it.

Boost PropertyTree delivers some quite unique features compared to other tree libraries. For instance it has a flexible leaf type built in, i.e. the data stored in different leaves may have different types. Though one could add this feature to other trees with a variant type in the leaves, but this adds another level of indirection. Another very nice feature is the parsing and generation of XML, JSON, INI and Info files. So, for simple data storing and reading tasks Boost PropertyTree provides everything out of the box.

Once you like to work with this tree structure, you might use it in other contexts as simple data handling. That leaves may hold different types comes in very handy, but one realizes quite soon, they may only hold types, which stream to and from string (at least if you use the default ptree with standard data type string ). So, we could provide the two stream operators for our data type, if we were free to add them (they could already be in use for user output etc.).

Luckily the authors help us in this respect and provide a customization point for PropertyTree, namely the struct translator_between . Next we need to get a fast and reliable string storage for custom types like:

Manually writing and parsing might still be ok for person_t but it gets quite cumbersome for data_t , even when using Boost Spirit. Again we rely on a solid solution by using Boost Serialization for this task. Since you might not be able to alter the type definitions, Boost Serialization allows to add the serialization feature externally to the types:

However, we need to tell our PropertyTree that it should use the serialization if available. As said we specialize the struct translator_between template.

This tells Boost PropertyTree, that it finds a translator type SerializationTranslator somewhere. We get some compiling problems because there are already some translator_between specializations available, and the compiler cannot figure out which to use for string . To get around that, we specialize again for our chosen string_type . You have to change the string_type accordingly if you're using a different string data type. To proceed we need to provide the translator:

We are providing a set and a get method, but the implementation is a little involved. There are a view points we need to handle:

  • Boost PropertyTree stores fundamental types by using their stream operators. This gives a short (no boiler plate) and human readable string representation.
  • Boost Serialization stores fundamental types automatically also by using the stream operators. However, the serialization is longer then the string and not human readable.
  • Boost PropertyTree might be used to read or write files to disk; it would be nice to have those as clean as possible. So, we should not use Boost Serialization for fundamental types.
  • For custom types, we might already have stream operators defined. It is quite likely that those are not build to store and restore values, but to communicate with the user. So, we won't use those.
  • Finally, to store a custom type in the tree we want to have a serialization to have it as type safe as possible.

We provide in each stream direction two functions. At most one of them is available for a given type, since the std::enable_if is complementary. In the enable if we check if a std::string could be constructed from the given type. This is true for the fundamental types and handles the stream operators for custom types. Additionally we enforce the existence of boost::serialization::serialize for custom types, which gives nicer compiler errors, if we try to store a custom type without serialization.

That is basically it. For each new type just add the corresponding serialize method and you are good to go.

Complete example

Here is the full example to play:

  • About - Imprint - Legal

Back to top

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

boost/property_tree/string_path.hpp

Revised $Date$

Copyright Beman Dawes, David Abrahams, 1998-2005.

Copyright Rene Rivera 2004-2008.

Distributed under the Boost Software License, Version 1.0 .

OSI Certified

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

boost/property_tree/ptree_fwd.hpp

Revised $Date$

Copyright Beman Dawes, David Abrahams, 1998-2005.

Copyright Rene Rivera 2004-2008.

Distributed under the Boost Software License, Version 1.0 .

OSI Certified

Search This Blog

C++ boost parse dynamically generated json string (not a file) -.

i trying make minimal example of reading json string passed command line arg boost. new c++ , boost.

my code is:

i calling like

but 'cannot open file error'. how boost read std::string or char* rather file?

what can read characters string stream, , pass read_json .

Post a Comment

Popular posts from this blog, html - sizing a high-res image (~8mb) to display entirely in a small div (circular, diameter 100px) -, java - intellij - no such instance method -, identifier - is it possible for an html5 document to have two ids -.

Subject: Re: [boost] [boost/foreach] What is wrong with BOOST_FOREACH(const std::string &name, m_modules)? From: Sebastian Redl ( sebastian.redl_at_[hidden] ) Date: 2011-09-10 06:24:02

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk

We've detected unusual activity from your computer network

To continue, please click the box below to let us know you're not a robot.

Why did this happen?

Please make sure your browser supports JavaScript and cookies and that you are not blocking them from loading. For more information you can review our Terms of Service and Cookie Policy .

For inquiries related to this message please contact our support team and provide the reference ID below.

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

Prev

Function template serialize

boost::property_tree::serialize

Description

Load or store the property tree using the given archive.

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt )

IMAGES

  1. C++ : Adding unnamed nodes to boost::property_tree::ptree

    boost ptree change value

  2. Using boost::property_tree

    boost ptree change value

  3. C++ : How to manually create a boost ptree with XML attributes?

    boost ptree change value

  4. Percentage Change

    boost ptree change value

  5. Electrical

    boost ptree change value

  6. 使用boost库完成读写JSON字符串

    boost ptree change value

VIDEO

  1. One Change ✅ Sales Boost ⬆️

  2. Scripted Device Creation Buttons Do Not Change Value or Status

  3. Video 3

  4. did your perm fruits change value?

  5. FarmVille2 Xp. Level Up in FV2 With CE

  6. How Radiologists Can Change Value-Based Care

COMMENTS

  1. How to modify node element with boost::property_tree and put_value

    Firstly, your code has UB, since modelModifier doesn't return a value.. The C-style cast in (std::string)it2.second.data() is extremely dangerous as it risks reinterpret_cast-ing unrelated types.There is no reason whatsoever for this kind of blunt casting. Just remove the cast! Also, ptreeIterator should probably take a ptree const&, not ptree&. With these fixed, the sample does NOT show the ...

  2. c++

    How do I parse all the sections that are present in the file and get the value for each key. That is, I have to parse section1, get the value for key1, key2, key3 . Proceed to section2 get the value for key1, key2 and key3. My .ini file looks something like this.

  3. Chapter 30. Boost.PropertyTree

    The Property Tree library provides a data structure that stores an arbitrarily deeply nested tree of values, indexed at each level by some key. Each node of the tree stores its own value, plus an ordered list of its subnodes and their keys. The tree allows easy access to any of its nodes by means of a path, which is a concatenation of multiple ...

  4. How to Access Data in a Property Tree

    In the former case, put will throw ptree_bad_data). Sample usage of put might appear as: ptree pt; pt. put ("a.path.to.float.value", 3.14f); Calling put will insert a new value at specified path, so that a call to get specifying the same path will retrieve it.

  5. Chapter 25. Boost.PropertyTree

    Example 25.1 uses boost::property_tree::ptree to store a path to a directory. This is done with a call to put().This member function expects two parameters because boost::property_tree::ptree is a tree structure that saves key/value pairs. The tree doesn't just consist of branches and twigs, a value must be assigned to each branch and twig.

  6. How to Access Data in a Property Tree

    How to Access Data in a Property Tree. Property tree resembles (almost is) a standard container with value type of pair<string, ptree> . It has the usual member functions, such as insert , push_back , find , erase , etc. These can of course be used to populate and access the tree. For example the following code adds key "pi" with data (almost ...

  7. Class template basic_ptree

    Description. Property tree main structure. A property tree is a hierarchical data structure which has one element of type Data in each node, as well as an ordered sequence of sub-nodes, which are additionally identified by a non-unique key of type Key. Key equivalency is defined by KeyCompare, a predicate defining a strict weak ordering.

  8. How to use boost::property_tree to load and write JSON

    Setting up. First, we need to include the libraries and load the file. // Short alias for this namespace namespace pt = boost::property_tree; // Create a root pt::ptree root; // Load the json file in this ptree pt::read_json("filename.json", root); Now, we have a populated property tree thatis waiting from us to look at him.

  9. How to store anything in Boost PropertyTree

    Boost PropertyTree stores fundamental types by using their stream operators. This gives a short (no boiler plate) and human readable string representation. Boost Serialization stores fundamental types automatically also by using the stream operators. However, the serialization is longer then the string and not human readable.

  10. Five Minute Tutorial

    It contains the log filename, a list of modules where logging is enabled, and the debug level value. First we need some includes: #include < boost / property_tree / ptree. hpp > #include < boost / property_tree / xml_parser. hpp > #include < boost / foreach. hpp > #include < string > #include < set > #include < exception > #include < iostream ...

  11. boost/property_tree/string_path.hpp

    A path is a sequence of values. Groups of values /// are separated by the separator value, which defaults to '.' cast to /// the sequence's value type. The group of values is then passed to the /// translator to get a key.

  12. boost/property_tree/detail/info_parser_read.hpp

    Boost C++ Libraries...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

  13. boost/property_tree/ptree_fwd.hpp

    template <typename Internal, typename External> struct translator_between; class ptree_error; class ptree_bad_data; class ptree_bad_path; // Typedefs /** Implements a path using a std::string as the key. */ typedef string_path<std::string, id_translator<std::string> > path; /** * A property tree with std::string for key and data, and default ...

  14. C++ boost parse dynamically generated json string (not a file)

    tl;dr : no. in versions of html, each element can have 1 id. see the spec : the id attribute specifies element's unique identifier (id). [dom] the value must unique amongst ids in element's home subtree , must contain @ least 1 character. the value must not contain space characters.

  15. Boost mailing page: Re: [boost] [boost/foreach] What is wrong with

    Subject: Re: [boost] [boost/foreach] What is wrong with BOOST_FOREACH(const std::string &name, m_modules)? From: Sebastian Redl (sebastian.redl_at_[hidden]) Date: 2011-09-10 06:24:02 Next message: Jeremiah Willcock: "Re: [boost] [iterator] counting_iterator and reverse iterator problem (was: [graph][iterators] csr graph and reverse iterator problem)" ...

  16. boost/property_tree/ptree.hpp

    A property tree is a hierarchical data. * structure which has one element of type @p Data in each node, as well. * as an ordered sequence of sub-nodes, which are additionally identified. * by a non-unique key of type @p Key. *. * Key equivalency is defined by @p KeyCompare, a predicate defining a.

  17. ValueCoach AI Tool Announced by ValueSelling Associates

    AI Supported Simulations and Role Play Boost Learning, Helping Sales Reps Close Bigger Deals Faster. May 21, 2024 08:30 ET | Source: ValueSelling Associates, Inc.

  18. Trans Mountain Pushed to Alter Limits to Boost Oil's Value

    May 10, 2024 at 12:06 PM PDT. Listen. 1:40. Oil companies including Chevron Corp., Canadian Natural Resources Ltd. and Suncor Energy Inc. are pressing the operators of the expanded Trans Mountain ...

  19. Boost property_tree: multiple values per key

    The standard property_tree handles only one string value per key since it is defined as: typedef basic_ptree<std::string, std::string> ptree; So, the only option is to use strings and parse them. I think the best method is to define a new class that stores the low and high values and then create a translator class for the get and set methods.

  20. Chapter 31. Boost.PropertyTree

    The Property Tree library provides a data structure that stores an arbitrarily deeply nested tree of values, indexed at each level by some key. Each node of the tree stores its own value, plus an ordered list of its subnodes and their keys. The tree allows easy access to any of its nodes by means of a path, which is a concatenation of multiple ...

  21. c++

    1. This is my first experience with boost::property_tree and I can't find a way to reproduce the way to get values from a tree following the documentation ( How to Access Data in a Property Tree ). This is the simple code that I wrote to experiment with a property tree: #include <iostream>. #include <string>.

  22. Function template serialize

    Description. Load or store the property tree using the given archive. The archive from which to load or save the serialized property tree. The type of this archive will determine whether saving or loading is performed. file_version for the archive. The property tree to load or save.