yaml-cpp
yaml-cpp copied to clipboard
Could you provide a method to dynamic access like this node("a","b","c",...)
As a user, sometimes we do not know how deep the yaml file will be. So it would be better if we can access the data like this YAML::Node node = YAML::LoadFile(file_path); T x = node("a","b","c",...).as<T>();
This makes it easier for users to encapsulate
What's wrong with a for loop?
What's wrong with a for loop?
What I mean is that if I want to encapsulate codes like this:
template <class T, typename... Args>
T GetField(Args... args){
std::vectorstd::string keys_container;
for(auto &v:{args...}){
keys_container.push_back(v);
}
for(int i = 0; i < node_config.size(); i++){
YAML::Node new_config = node_config[i];
for (auto nitr = keys_container.begin(); nitr != keys_container.end(); nitr++){
if(new_config[*nitr]){
c = new_config[*nitr];
}
}
T x = new_config.as<T>();
return x;
}
It will failed because the refactor of "=" is quote like &. When change new_config, it will also change node_config which is not want to see. If I use Clone(), the run time is too long because the data copy. Thus, I do not know how to loop call []. Can you give me some advices? Or do you have any suggestions to achieve it in a proper way?
thank you so much
I am facing the same issue. use for loop to walk from root node to leaf node will cause the root node value changed.
What's wrong with a for loop?
What I mean is that if I want to encapsulate codes like this:
template <class T, typename... Args> T GetField(Args... args){ std::vectorstd::string keys_container; for(auto &v:{args...}){ keys_container.push_back(v); } for(int i = 0; i < node_config.size(); i++){ YAML::Node new_config = node_config[i]; for (auto nitr = keys_container.begin(); nitr != keys_container.end(); nitr++){ if(new_config[*nitr]){ c = new_config[*nitr]; } } T x = new_config.as(); return x; }
It will failed because the refactor of "=" is quote like &. When change new_config, it will also change node_config which is not want to see. If I use Clone(), the run time is too long because the data copy. Thus, I do not know how to loop call []. Can you give me some advices? Or do you have any suggestions to achieve it in a proper way?
the use of std::array inspired me. Here's my inelegant solution:
static inline std::vector<std::string> stringSplit(const std::string &str,
const char delimiter) {
std::string tok;
std::stringstream ss(str);
std::vector<std::string> vec;
while (std::getline(ss, tok, delimiter)) {
vec.push_back(tok);
}
return vec;
}
static inline YAML::Node getNodeByPath(YAML::Node root,
const std::string &path) {
std::vector<YAML::Node> n{root};
auto parts = stringSplit(path, '.');
for (const auto &name : parts) {
// std::string lower;
// std::transform(part.begin(), part.end(), std::back_inserter(lower),
// tolower);
auto child = n[n.size() - 1][name];
if (child) {
n.push_back(child);
continue;
}
return child;
}
return n[n.size() - 1];
}
template <typename... Args>
static inline YAML::Node getNode(YAML::Node root, Args... args) {
std::vector<YAML::Node> n{root};
for (const auto &name : {args...}) {
auto child = n[n.size() - 1][name];
if (child) {
n.push_back(child);
continue;
}
return child;
}
return n[n.size() - 1];
}
TEST_CASE("parse", "[yaml]") {
auto cfg = YAML::LoadFile("/home/chris/work/cxx/full.yml");
auto nodeA = getNodeByPath(cfg, "root.certificate.ca");
auto nodeB = getNodeByPath(cfg, "root.certificate.client");
auto nodeC = getNode(cfg, "webcam", "cloud", "server");
auto nodeD = getNode(cfg, "webcam", "database", "path");
SPDLOG_INFO("cfg = {}", YAML::Dump(cfg));
SPDLOG_INFO("nodeA = {}", YAML::Dump(nodeA));
SPDLOG_INFO("nodeB = {}", YAML::Dump(nodeB));
SPDLOG_INFO("nodeC = {}", YAML::Dump(nodeC));
SPDLOG_INFO("nodeD = {}", YAML::Dump(nodeD));
}
I am facing the same issue. use for loop to walk from root node to leaf node will cause the root node value changed.
Have your problem solved?
I am facing the same issue. use for loop to walk from root node to leaf node will cause the root node value changed.
Have your problem solved?
I am using the code above as workaround.