I am trying to use the Boost property trees to read INI
files containing properties within sections have a "composed" path name.
For example my INI
file looks like this:
[my.section.subsection1]
someProp1=0
[my.section.subsection2]
anotherProp=1
I read it with the following code:
namespace pt = boost::property_tree;
pt::ptree propTree;
pt::read_ini(filePath, propTree);
boost::optional<uint32_t> someProp1 = pt.get_optional<uint32_t>("my.section.subsection1.someProp1");
The problem is that I never get the value of someProp1
...
When I iterate over the first tree level I see the the entire section name my.section.subsection1
as a key. Is there a way to make the read_ini
function to parse section names with dots as a tree hierarchy?
If you want the property tree to reflect the hierarchy, then it requires writing a custom parser. Per the INI parser documentation:
INI is a simple key-value format with a single level of sectioning. [...] not all property trees can be serialized as INI files.
Because of the single level sectioning, my.section.subsection1
must be treated as a key, rather than a hierarchy path. For example, the my.section.subsection1.someProp1
path could be broken down into:
key separator value
.----------^---------. ^ .---^---.
|my.section.subsection1|.|someProp1|
Because "." is part of the key, the boost::property_tree::string_path
type must be explicitly instantiated with a different separator. It is available as a path_type
typedef on ptree
. In this case, I have opted to use "/":
ptree::path_type("my.section.subsection1/someProp1", '/')
With example.ini containing:
[my.section.subsection1]
someProp1=0
[my.section.subsection2]
anotherProp=1
The following program:
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
int main()
{
namespace pt = boost::property_tree;
pt::ptree propTree;
read_ini("example.ini", propTree);
boost::optional<uint32_t> someProp1 = propTree.get_optional<uint32_t>(
pt::ptree::path_type( "my.section.subsection1/someProp1", '/'));
boost::optional<uint32_t> anotherProp = propTree.get_optional<uint32_t>(
pt::ptree::path_type( "my.section.subsection2/anotherProp", '/'));
std::cout << "someProp1 = " << *someProp1
<< "\nanotherProp = " << *anotherProp
<< std::endl;
}
Produces the following output:
someProp1 = 0
anotherProp = 1