c++pugixml

Pass variable to PUGIXML xml_tree_walker


I am using pugixml to parse a file. I have been using an xml_tree_walker and I have a variable I want to modify as the walker walks through the xml. I am currently using a global variable but don't want to. Is there a way to pass a variable to the walker by reference? If this is the case, would that mean I would need to modify the for_each function prototype in the pugixml source?

Below is the way I am currently using the walker.

struct simple_walker: pugi::xml_tree_walker
{
    virtual bool for_each(pugi::xml_node& node)
    {
        for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation

        std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";

        some_global = node.name(); // I don't want this to be a global

        return true; // continue traversal
    }
};

I am calling the walker like so:

pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(XML_FILE);

simple_walker mySimpleWalker;
doc.traverse(mySimpleWalker);

Solution

  • One thing you can do is keep a member reference in your walker to the object you are capturing information in. Something like:

    struct captured_info // where my captured info goes
    {
        std::string name;
        int value;
        std::time_t date;
        // ...
    };
    
    struct simple_walker: pugi::xml_tree_walker
    {
        // must supply a captured_info object to satisfy
        // this constructor
        simple_walker(captured_info& info): info(info) {}
    
        virtual bool for_each(pugi::xml_node& node)
        {
            for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation
    
            std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";
    
            info.name = node.name(); 
            info.value = std::stoi(node.value()); 
            // ... etc
    
            return true; // continue traversal
        }
    
        captured_info& info;
    };
    
    
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(XML_FILE);
    
    captured_info info; // the output!!!
    simple_walker mySimpleWalker(info); // configure for output
    doc.traverse(mySimpleWalker);
    
    std::cout << info.name << '\n'; // etc...