how to get properties within subsections of a ini file with boost property tree?

gre*_*det 3 ini boost boost-propertytree ptree

I am trying to use the Boost property trees to read INIfiles containing properties within sections have a "composed" path name.

For example my INIfile looks like this:

[my.section.subsection1]
someProp1=0

[my.section.subsection2]
anotherProp=1
Run Code Online (Sandbox Code Playgroud)

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");
Run Code Online (Sandbox Code Playgroud)

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?

Tan*_*ury 6

如果您希望属性树反映层次结构,则需要编写自定义解析器。根据 INI 解析器文档

INI 是一种简单的键值格式,具有单级分段。[...] 并非所有属性树都可以序列化为 INI 文件。

由于是单级分段,my.section.subsection1必须将其视为键,而不是层次路径。例如,my.section.subsection1.someProp1路径可以分解为:

           key    separator  value 
 .----------^---------. ^ .---^---.
|my.section.subsection1|.|someProp1|
Run Code Online (Sandbox Code Playgroud)

因为 ”。” 是键的一部分,boost::property_tree::string_path必须使用不同的分隔符显式实例化该类型。它可以作为一个path_type上的typedef ptree。在这种情况下,我选择使用“/”:

 ptree::path_type("my.section.subsection1/someProp1", '/')
Run Code Online (Sandbox Code Playgroud)

使用 example.ini 包含:

 ptree::path_type("my.section.subsection1/someProp1", '/')
Run Code Online (Sandbox Code Playgroud)

以下程序:

[my.section.subsection1]
someProp1=0

[my.section.subsection2]
anotherProp=1
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

#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;
}
Run Code Online (Sandbox Code Playgroud)