1

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);
EngineerCamp
  • 661
  • 1
  • 6
  • 16
  • Make `some_global` a member variable of `simple_walker`? How are you creating it and calling the `pugi` API? – Galik Jan 14 '19 at 23:06
  • @Galik I added how I am creating and calling it to the question. The variable is actually another structure, which the walker will be used to modify some of that structures members. This structure will be used/modified by other functions, so I am not sure that it makes sense for it to be a member variable of the `simple_walker` struct? – EngineerCamp Jan 14 '19 at 23:18
  • Having structures as members is not a problem. But it depends on if you need that structure to be somewhere else (or who needs to own it). It's difficult without knowing the whole picture but if not a member variable as a value, then what about a member variable as a *reference*? – Galik Jan 14 '19 at 23:22

1 Answers1

2

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...
Galik
  • 47,303
  • 4
  • 80
  • 117