ImJimmi
ImJimmi

Reputation: 98

Call different processing functions for attributes in an XML element

When handling XML attributes in C++, how should different operations be run for different attributes?

Currently, I have something like this:

// get list of attributes for an XML element into member called 'attributes'
// ...

// run appropriate functions for each attribute
for (auto attribute : attributes)
{
    auto name = attribute.name;
    auto value = attribute.value;

    if (name == "x")
        doSomethingWithX(value);
    else if (name == "y")
        doSomethingWithY(value);
}

For just a few attribute names, this isn't so bad - but with a larger number (>15) this starts to look messy and I'm concerned about performance issues.

What might be a better way of handling XML attributes like this?

Upvotes: 6

Views: 138

Answers (1)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

You can use a std::unordererd_map<std::string, std::function<void (const std::string&)>> and set it up with appropriate lambda functions:

std::unordererd_map<std::string, std::function<void (const std::string&)>> attrProcessors = {
    { "X", [](const std::string& value) {
           // Do something with value
           } } } ,
    { "Y", [](const std::string& value) {
           // Do something with value
           } } }
};

// run appropriate functions for each attribute
for (auto attribute : attributes)
{
    auto name = attribute.name;
    auto value = attribute.value;

    auto processorEntry = attrProcessors.find(name);

    if(processorEntry != attrProcessors.end()) {
       (*processorEntry).second(value);
    }
}

I am not so sure though that maintenace of the map entries would be easier to read than the if / else if cascade.
On the other hand you won't need to create an extra function for each attribute name.

Upvotes: 2

Related Questions