tzippy
tzippy

Reputation: 6648

Parsing xml file with boost property_tree and put selected content to a std::map

From a java property XML file I want to find each element named entry (inside the root element properties). Then put the content of its attribute key in a std::map<std::string, std::string> as key and the content of the element (between <entry> and </entry>) as value. So far I am using boost property_tree. But since I'm unfamiliar with parsing XML documents, I was wondering if there are any pitfalls that I don't see here or whether there's a simpler approach than this.

std::map<std::string, std::string> mMap;
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("properties"))
{
    if (v.first == "entry")
    {
        std::string sVal = v.second.get_child("<xmlattr>.key").data();

        if (sVal.compare("Foo") == 0)
            mMap[sVal] = v.second.data();
        else if (sVal.compare("Bar") == 0)
            mMap[sVal] = v.second.data();
        else if(...)
    }
}

XML:

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="Foo">This is a sentence.</entry>
    <entry key="Bar">And another one.</entry>
    <entry key=...
</properties>

Upvotes: 1

Views: 751

Answers (1)

sehe
sehe

Reputation: 393789

I'd make it simpler:

Live On Coliru

Map read_properties(std::string const& fname) {
    boost::property_tree::ptree pt;
    read_xml(fname, pt);

    Map map;

    for (auto& p : pt.get_child("properties")) {
        auto key = p.second.get<std::string>("<xmlattr>.key");
        if (!map.insert({ key, p.second.data() }).second)
            throw std::runtime_error("Duplicate key: " + key);
    }

    return map;
}

If you crave more validation or "XPath" feel, I'd suggest using an XML library.

Other than that, I see not a lot wrong.

Upvotes: 1

Related Questions