Frage

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

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?

War es hilfreich?

Lösung

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top