0

I am reading some information and I want to write it in json, but the names of some keys contain dots in the name. I want to get something like this:

{
  "programs":
   {
      "tmp.exe" : "D:\\Directory\\Directory",
      "foo.exe" : "C:\\Directory"
   }
}

This is my code:

ptree pt;
ptree name;

name.put(string_name,string_directory);
pt.add_child("programs",name);

But it turns out the following:

    {
      "programs":
       {
          "tmp":
              {
                "exe" : "D:\\Directory\\Directory"
              },
          "foo": 
              {
                "exe" : "C:\\Directory"
              }
       }
    }

I was thinking about adding it as a child. But this code does not work at all

ptree pt;
ptree name;

name.put("",string_name);
pt.add_child("programs",name);
pt.find(string_name).put_value(string_directory);
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
AlexChek
  • 13
  • 2
  • Your keys should normally be quoted strings. `{ "programs" : { "temp.exe" : "d:\\Directory\\directory", "foo.exe" : "c:\\Directory" } }`. If that's not what you're getting you may simply want to switch to a better JSON library. – Jerry Coffin Sep 08 '21 at 20:49
  • 1
    Boost property tree isn't the best JSON library, it has a number of limitations, you'd be better off with a dedicated JSON library – Alan Birtles Sep 08 '21 at 20:59
  • Start with some _valid_ JSON. You can use an online site like https://jsonlint.com/ to check it. Hint: Your JSON isn't close to valid as is. – Ted Lyngmo Sep 08 '21 at 21:08
  • This is just an example for clarity. The main problem is that I need to set a key with a dot in the name. I can't use libraries other than boost in this project – AlexChek Sep 08 '21 at 21:21
  • @AlexChek I'm afraid it doesn't clarify anything when what you show is invalid JSON. When you say you _can't_ use other libraries, is that because you don't know how or because you aren't allowed? – Ted Lyngmo Sep 08 '21 at 21:48
  • @TedLyngmo I wrote an example from memory and from the phone. I have edited it now. I am not allowed to use other libraries, no matter how much I would like to – AlexChek Sep 08 '21 at 22:02
  • @AlexChek Ok, I see. The JSON you aim for is still invalid so it's hard to say what you should do to correct your code. Use the JSON linter I linked to above to validate that what you aim for can actually be done. – Ted Lyngmo Sep 08 '21 at 22:05
  • I checked it, it is considered valid – AlexChek Sep 08 '21 at 22:21
  • 1
    FWIW: I searched for "dot" in the [tag:boost-propertytree] tag (i.e. I typed `[boost-propertytree] dot` in the search field of this site). Top hit was a duplicate of what I proposed as a duplicate for this. – JaMiT Sep 08 '21 at 22:25
  • Thank you, this is exactly what I was looking for@JaMiT – AlexChek Sep 09 '21 at 00:10

1 Answers1

2

Although all JSON linters I've tested accepts your target JSON as valid and boost::property_tree::read_json parses it, actually creating it is a bit cumbersome. This is because boost::property_tree uses . as a path separator by default.

To overcome this, you can specify the Key with a different ptree::path_type than the default in which you specify another character. I've used \ as a path separator here because that's unlikely going to be a part of the basenames of your files.

Example:

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

#include <iostream>

int main() {
    using namespace boost::property_tree;

    try {
        ptree pt;
        ptree name;

        name.put(ptree::path_type{"tmp.exe", '\\'}, "D:\\Directory\\Directory");
        name.put(ptree::path_type{"foo.exe", '\\'}, "C:\\Directory");

        pt.add_child("programs", name);
        write_json(std::cout, pt);

    } catch(const std::exception& ex) {
        std::cout << "exception: " << ex.what() << '\n';
    }
}

Output:

{
    "programs": {
        "tmp.exe": "D:\\Directory\\Directory",
        "foo.exe": "C:\\Directory"
    }
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108