12

I am trying to use filenames as the key in boost::PropertyTree

However, the '.' character in a filename such as "example.txt" causes an additional layer to be added within the property tree. The most obvious solution would be to replace '.' with another character, but there is likely a better way to do this, such as with an escape character.

In the following example, the value 10 will be put in the node 'txt', a child of 'example'. Instead, I want the value 10 to be stored in the node 'example.txt'.

ptree pt;
pt.put("example.txt", 10);

How can I use the full filename for a single node?

Thanks in advance for your help!

Andrew Hundt
  • 2,551
  • 2
  • 32
  • 64
  • An aside: Using filenames as keys is tricky. Have you considered what happens when there are hardlinks? Symbolic links? Renames that occur outside your process? Case insensitivity on Windows? The fact that Windows truncates trailing spaces in filenames? – asveikau Dec 22 '09 at 20:14
  • Fortunately this is for a read only operation with a precondition that the contents of the directory will not change during this operation. However, I appreciate you pointing out the additional concerns. – Andrew Hundt Dec 22 '09 at 20:29
  • My point is that some of these things (like the existence of links) could cause false negatives. Just something to keep in mind, especially if you were to use this for some kind of a security feature. – asveikau Dec 22 '09 at 21:17

2 Answers2

12

Just insert the tree explicitly:

pt.push_back(ptree::value_type("example.txt", ptree(10)));

The put method is simply there for convenience, which is why it automatically parses . as an additional layer. Constructing the value_type explicitly like I have shown above avoids this problem.

An alternative way to solve the problem is to use an extra argument in put and get, which changes the delimeter.

pt.put('/', "example.txt", "10");
pt.get<string>('/', "example.txt");

For the record, I've never used this class before in my life. I got all this information right from the page you linked to ; )

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • Small mistake in your line, it needs to be pt.push_back(ptree::value_type("example.txt", ptree("10"))); This also begs the question, how do I get this child now that the get operation also fails due to the '.' character, and how do I put without giving it a data value such as example.txt>wordCount>10? – Andrew Hundt Dec 22 '09 at 21:10
  • Edited my post to answer your question. – Peter Alexander Dec 23 '09 at 05:54
  • Unfortunately, put does not support alternate delimiters. so pt.put('/', "example.txt", "10"); cannot be used. While I did replacement of '.' with another character myself outside of the function, it does not look like that is built in. – Andrew Hundt Jan 05 '10 at 17:37
8

The problem was that the documentation was outdated. A path type object must be created as follows, with another character that is invalid for file paths specified as the delimiter as follows:

pt.put(boost::property_tree::ptree::path_type("example.txt", '|'), 10);

I found a path to the solution from the boost mailing list at the newsgroup gmane.comp.lib.boost.devel posted by Philippe Vaucher.

Hauleth
  • 22,873
  • 4
  • 61
  • 112
Andrew Hundt
  • 2,551
  • 2
  • 32
  • 64