Accessing values using a boost::property_tree::str

2019-07-15 07:41发布

问题:

I am playing with boost::property_tree::ptree, using namely the following json file:

{
    "menu":
    {
        "foo": "true",
        "bar": "true",
        "value": "102.3E+06",
        "popup":
        [
            {
                "value": "New",
                "onclick": "CreateNewDoc()"
            },
            {
                "value": "Open",
                "onclick": "OpenDoc()"
            }
        ]
    }
}

I have been trying to access nested "value" with no luck so far, here is what I did:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>

int main(int argc, char *argv[])
{
  const char *filename = argv[1];
  using boost::property_tree::ptree;
  ptree pt;

  read_json(filename, pt);

  std::string v0 = pt.get<std::string>("menu.value"); // ok
  //std::string v1 = pt.get<std::string>("menu.popup.value"); // not ok
  //std::string v2 = pt.get<std::string>("menu.popup.1.value"); // not ok
  //std::string v3 = pt.get<std::string>("menu.popup.''.value"); // not ok

  // ugly solution:
  BOOST_FOREACH(ptree::value_type &v,
    pt.get_child("menu.popup"))
    {
    const ptree &pt2 = v.second;
    std::string s = pt2.get<std::string>("value");
    }
  return 0;
}

All my attempts "not ok" failed so far. It seems that string_path does not allow accessing the whole ptree, as one could imagine (think XPath in XML world). Or am I missing something ?

回答1:

Property tree (as of 1.54) doesn't support arrays. You can see how the JSON ptree serializer translates JSON array objects into suitable (unnamed; key="") nodes here.

Ptree's string paths resolve values by a key path (where key names are separated by dots). Since the array objects end up as unnamed nodes, there's no way to access individual nodes without iterating the children of the root node (in this case "popup"). You can read up on how to use the various get() overloads here

Ptree's five minute example uses an XML source that has an element ("modules") with an array of children (each named "module"). Just like in your case, the only way to properly access each one is to iterate get_child()'s results