c++boostxml-parsingboost-foreach

Trouble using get_value with Boost's property trees


I have to write an XML parser with Boost. However I have some trouble. I can access the nodes name without any problem, but for some reason I can't access the attributes inside a tag by using get_value, which should work instantly. Maybe there is a mistake in my code I didn't spot? Take a look:

void ParametersGroup::load(const boost::property_tree::ptree &pt)
{
  using boost::property_tree::ptree;
  BOOST_FOREACH(const ptree::value_type& v, pt)
  {
    name = v.second.get_value<std::string>("name"); 
    std::string node_name = v.first;
    if (node_name == "<xmlattr>" || node_name == "<xmlcomment>")
      continue;
    else if (node_name == "ParametersGroup")
      sg.load(v.second); // Recursion to go deeper
    else if (node_name == "Parameter")
    {
      // Do stuff
      std::cout << "PARAMETER_ELEM" << std::endl;
      std::cout << "name: " << name << std::endl;
      std::cout << "node_name: " << node_name << std::endl << std::endl;
    }
    else
    {
      std::cerr << "FATAL ERROR: XML document contains a non-recognized element: " << node_name << std::endl;
      exit(-1);
    }
  }
}

So basically I ignore and tags, when I'm in a ParametersGroup tag I go deeper, and when I'm in a Parameter tag I recover the datas to do stuff. However, I can't get the "name" properly.

This is the kind of lines I'm scanning in the last else if :

<Parameter name="box">

The std::cout << name displays things like that:

name: ^M
^M
  ^M
^M
  ^M
^M

which is obvisouly not what I'm asking for.

What am I doing wrong? Any help would be greatly appreciated.


Solution

  • Since your question isn't particularly selfcontained, here's my selfcontained counter example:

    Live On Coliru

    #include <sstream>
    #include <iostream>
    
    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/xml_parser.hpp>
    
    using namespace boost::property_tree;
    
    int main() {
        ptree pt;
    
        std::istringstream iss("<Parameter name=\"box\" />");
        xml_parser::read_xml(iss, pt);
    
        for (auto& element : pt)
        {
            std::cout << "'" << element.first << "'\n";
            for (auto& attr : element.second)
            {
                std::cout << "'" << attr.first << "'\n";
                for (auto& which : attr.second)
                {
                    std::cout << "'" << which.first << "': \"" << which.second.get_value<std::string>() << "\"\n";
                }
            }
        }
    }
    

    It prints

    'Parameter'
    '<xmlattr>'
    'name': "box"
    

    I hope you can see what you need to do (likely an unexpected level of nodes in the tree?). To get directly to the leaf node:

    pt.get_child("Parameter.<xmlattr>.name").get_value<std::string>()