2

I followed this link http://www.technical-recipes.com/2014/using-boostproperty_tree/ to parse the xml. But how can I read the entire xml without the specifying a particular key? I tried the below code but it is unable to process it and I am getting the error as No such node.

Code:

const std::string XML_PATH1 = "./test1.xml";
#define ROOTTAG  "roottag"
boost::property_tree::ptree pt1;
boost::property_tree::read_xml( XML_PATH1, pt1);
BOOST_FOREACH(boost::property_tree::ptree::value_type & node, pt1.get_child(ROOTTAG))
{
    std::string tagname = node.first;
    tagname += ".";
    boost::property_tree::ptree subtree = node.second;
    BOOST_FOREACH( boost::property_tree::ptree::value_type & v, subtree.get_child(node.first.data()))
    {
        //does not enter here
        tagname += v.first.data();
        tagname += ".";
        xmlmap[tagname] = tagvalue;
     }
}

What has to be specified in the second loop instead of node.first.data()?

BOOST_FOREACH( boost::property_tree::ptree::value_type & v, subtree.get_child(node.first.data())) 

Please note that I have to use BOOST_FOREACH itself and use the same method. I referred many websites but could not find how to read entire xml without specifying a particular key.

Also, how to read multi-level xml using the above method?

Namitha
  • 355
  • 1
  • 6
  • 17
  • 3
    You've been asking the same [since feb 10th](http://stackoverflow.com/questions/35314178/c-how-to-read-xml-using-boost-xml-parser-and-store-in-map). What does it take for us to be relieved? Can you /just/ show expected input and output? – sehe Feb 19 '16 at 10:15

1 Answers1

1

Of course, the whole "I want to flatten this into a map" looks to be a futile exercise, as I argued in my answer here:

However, since you seem intent and just can't come up with the code to iterate a ptree recursively, here's a start:

Live On Coliru

void flatten(boost::property_tree::ptree const& pt, Flat& xmlmap, std::string const& prefix = "") {
    using namespace boost::property_tree;

    bool has_child_elements = false;
    BOOST_FOREACH (ptree::value_type const& child, pt) {
        has_child_elements |= (child.first != "<xmlattr>");
        flatten(child.second, xmlmap, prefix + "." + child.first);
    }

    if (!has_child_elements) {
        std::string val = pt.get_value("");
        if (!val.empty())
            xmlmap[prefix] = val;
    }
}

When you call this like so:

int main() {
    boost::property_tree::ptree pt;
    boost::property_tree::read_xml("test.xml", pt);

    Flat m;
    flatten(pt.get_child("roottag"), m, "DEMO");

    BOOST_FOREACH(Flat::value_type const& p, m) {
        std::cout << p.first << "\t= '" << p.second << "'\n";
    }
}

It prints e.g.

DEMO.billTo.<xmlattr>.country   = 'US'
DEMO.billTo.city    = 'Old Town'
DEMO.billTo.name    = 'Robert Smith'
DEMO.billTo.state   = 'PA'
DEMO.billTo.street  = '8 Oak Avenue'
DEMO.billTo.zip = '95819'
DEMO.comment    = 'Hurry, my lawn is going wild!'
DEMO.items.item.<xmlattr>.partNum   = '926-AA'
DEMO.items.item.USPrice = '39.98'
DEMO.items.item.comment = 'Confirm this is electric'
DEMO.items.item.productName = 'Baby Monitor'
DEMO.items.item.quantity    = '1'
DEMO.items.item.shipDate    = '1999-05-21'
DEMO.shipTo.<xmlattr>.country   = 'US'
DEMO.shipTo.city    = 'Mill Valley'
DEMO.shipTo.name    = 'Alice Smith'
DEMO.shipTo.state   = 'CA'
DEMO.shipTo.street  = '123 Maple Street'
DEMO.shipTo.zip = '90952'
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Sample [Live On Coliru](http://coliru.stacked-crooked.com/a/491531c7f187e00e) – sehe Feb 19 '16 at 10:20
  • How to handle scenarios where it has multiple child with same name, the value gets overwritten in map – Namitha Mar 07 '16 at 08:21
  • or how to store child with same name as comma separated values in the map? – Namitha Mar 07 '16 at 08:23
  • Use add instead of put. From the top of my head. The documentation might help – sehe Mar 07 '16 at 08:23
  • in flatten method where the data is being added to map, there what to do? – Namitha Mar 07 '16 at 08:26
  • Use add instead of put. From the top of my head. The documentation might help. http://stackoverflow.com/questions/16136605/adding-nodes-with-the-same-key-to-a-property-tree – sehe Mar 07 '16 at 08:28
  • The link provided by you, tells how to write to an xml file, what I am asking you is how to read such values and put into map by separating each value by a comma. – Namitha Mar 07 '16 at 14:39
  • Oh. Well. That's a simple loop. I don't see what help you could require there. Perhaps you can just post a question instead of coming back to old questions with more questions. – sehe Mar 07 '16 at 21:45
  • In the sample code on coliru, I see that the value for Lawnmower is missing. It only has baby monitor, how to get both values? – Namitha Mar 14 '16 at 11:14
  • @mooli It's not "missing". It's "overwritten". Obviously, because the paths are the same. It's your work to decide a way to handle duplicate keys. Did I mention [flattening might not be what you want](http://stackoverflow.com/questions/35314178/c-how-to-read-xml-using-boost-xml-parser-and-store-in-map/35318635#35318635)? – sehe Mar 14 '16 at 11:30