I'd like to create a class that can be constructed from a property tree, as in this example:
<?xml version="1.0" encoding="utf-8"?>
<config>
<name>testing</name>
<!-- Test property tree -->
<lambda min="200000" max="200">100</lambda>
...
That is easy with a property tree, but then I need to access two properties of a subtree, as in this class:
parameter::parameter(boost::property_tree::ptree t)
{
// Set the value
value = t.get_value<double>();
// ?????
auto nodename = t.something();
// ?????
std::string nodepath = t.somethingelse();
// Get the attributes (or empty)
auto p = t.get_child("<xmlattr>", boost::property_tree::ptree());
// If we have attributes, read them
if (p != boost::property_tree::ptree())
{
min = t.get<double>("<xmlattr>.min");
max = t.get<double>("<xmlattr>.max");
if (min > max)
throw std::runtime_error("Min and max values invalid for the parameter " + nodename + ", path: " + nodepath);
}
else
{
min = +1.0;
max = -1.0;
}
}
// ... Someplace else
lambda = parameter(config.get_child("config.lambda"));
In the XML the mim/max attributes for lambda
are invalid, and I need to throw an exception that could be read as
Min and max values invalid for the parameter lambda, path: config.lambda
Of course I could just pass the string, but it would defat the purpose. I've tried messing around t
's iterator and data
, but got nothing.
Can I obtain those values from a ptree
?
Thanks!
I'd slightly shuffle the interface around so you don't drop the information you need prematurely:
#include <boost/property_tree/xml_parser.hpp>
using boost::property_tree::ptree;
struct parameter {
parameter(ptree const& tree, ptree::path_type const& nodepath)
{
ptree const& t = tree.get_child(nodepath);
// Set the value
value = t.get_value<double>();
auto nodename = [nodepath] {
auto copy = nodepath;
while (!copy.single()) copy.reduce();
return copy.reduce();
}();
// Get the attributes (or empty)
auto p = t.get_child("<xmlattr>", boost::property_tree::ptree());
// If we have attributes, read them
if (p != boost::property_tree::ptree())
{
auto min = t.get<double>("<xmlattr>.min");
auto max = t.get<double>("<xmlattr>.max");
if (min > max)
throw std::runtime_error("Min and max values invalid for the parameter " + nodename + ", path: " + nodepath.dump());
}
else
{
min = +1.0;
max = -1.0;
}
}
private:
double min, max;
double value;
};
int main() {
ptree config;
std::ifstream xml("input.txt");
read_xml(xml, config);
auto lambda = parameter(config, "config.lambda");
}
Prints
terminate called after throwing an instance of 'std::runtime_error'
what(): Min and max values invalid for the parameter lambda, path: config.lambda