为什么 Boost 属性树 write_json 将所有内容保存为字符串?有可能改变这一点吗?
我正在尝试使用 boost 属性树 write_json 进行序列化,它将所有内容保存为字符串,并不是数据错误,而是我每次都需要显式地转换它们,并且我想在其他地方使用它们。 (就像在 python 或其他 C++ json(非 boost)库中一样)
这里是一些示例代码以及我根据语言环境得到的内容:
boost::property_tree::ptree root, arr, elem1, elem2;
elem1.put<int>("key0", 0);
elem1.put<bool>("key1", true);
elem2.put<float>("key2", 2.2f);
elem2.put<double>("key3", 3.3);
arr.push_back( std::make_pair("", elem1) );
arr.push_back( std::make_pair("", elem2) );
root.put_child("path1.path2", arr);
std::stringstream ss;
write_json(ss, root);
std::string my_string_to_send_somewhare_else = ss.str();
并且 my_string_to_send_somewhere_else
是某物。像这样:
{
"path1" :
{
"path2" :
[
{
"key0" : "0",
"key1" : "true"
},
{
"key2" : "2.2",
"key3" : "3.3"
}
]
}
}
有没有办法将它们保存为值,例如:
“key1”:true
还是“key2”:2.2
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
好吧,我已经像这样解决了它,(当然它并不适合所有人,因为它有点黑客,需要进一步的工作)。
我编写了自己的
write_json
函数(只需将文件json_parser.hpp
和json_parser_write.hpp
复制到我的项目中)并修改以下内容json_parser_write.hpp
中的行:流<< Ch('"') << 数据 << Ch('"'); ==>流<< data;
那么除了字符串之外的值将被正确保存,所以我为它编写了自定义翻译器:
并简单地使用以下方法保存了字符串:
完整的程序:
结果:)
Ok, I've solved it like this, (of course it won't suite for everybody, as it is a bit of a hack, that need further work).
I've wrote my own
write_json
function (simply copied the files,json_parser.hpp
andjson_parser_write.hpp
to my project) and modified the following lines injson_parser_write.hpp
:stream << Ch('"') << data << Ch('"'); ==> stream << data;
Then values will be saved properly except for strings, so I wrote custom translator for it:
and simply saved string using:
complete program:
result :)
Boost 确认其实现并非 100% 符合 JSON 标准。检查以下链接以查看他们的解释:
制作一个保留 JSON 类型的 ptree 变体是未来的计划,但还很遥远。 !
Boost confirms its implementation has no 100% conformance to JSON standard. Check the following link to see their explanation:
Making a ptree variant that preserves JSON types is a future plan, but far off.!
我最终在我的实用程序中添加了另一个函数来解决这个问题:
希望有帮助。
I ended up adding another function to my utils to solve this:
Hope that helps.
我能想到的最简单、最干净的解决方案是生成带有占位符的 JSON,并在最后用实际值替换字符串,从而放弃额外的引号。
结果是
The simplest and cleanest solution that i could come up with was generating the JSON with placeholders and in the end string replacing with the actual value ditching the extra quotes.
And the result is
因为我们有 typedef basic_ptree;树;在 boost 库中,boost 始终将每个值序列化为字符串,并将所有值解析为等效的字符串。
As we have typedef basic_ptree<std::string, std::string> ptree; in the boost libraries, boost will always serialize each value as string and parse all values to a string equivalent.
从输出的 JSON 可以清楚地看出,序列化程序使用某种 .toString() 方法将所有内容序列化为字符串 - 也就是说,它不知道每个成员的类型,因此将所有内容都包含在“”中。
有关详细信息,请参阅使用属性树在 Boost 中创建 JSON 数组这个问题。
From the outputted JSON it is clear that the serializer serializes everything to strings using some sort of .toString() method - that is, its unaware of the type of each member and so encloses everything in " ".
See Creating JSON arrays in Boost using Property Trees for more about this problem .
所有需要显式自定义字符串翻译器的解决方案对我来说似乎很容易出错,因为有时可能会忘记它。最好通过继承为属性树的 put 方法提供某种重载方式来隐式处理此问题,但这不可能以稳健的方式进行,因为它是模板,并且您必须确保树的所有方法的完全协变。如果可能的话,一般情况下也应该避免改变 boost 库的内容作为解决方法。
到目前为止,我发现的最可靠的无黑客方法是(自 C++11 起):
>
的 boost-property 树优点:
缺点:
有关更多详细信息,例如,请参阅
http:// marko-editor.com/articles/property_tree_store_anything/
您可以轻松地调整它以适应变体的使用。
All solutions, that require custom translators for strings explicitly, seem to be quite error prone for me since it's likely to forget it sometimes. It would be nice to have some kind of overload way via inheritance for the property tree's put method to handle this implicitly but that's not possible in a robust way since it's a template and you would have to ensure full covariance for all methods of the tree. Also changing boost library stuff as a workaround should be avoided in general if possible.
The most robust way without hacks I found so far is (since C++11):
<KeyType, std::variant<yourTypes>>
Pros:
Cons:
For more details, for instance see
http://marko-editor.com/articles/property_tree_store_anything/
You can easily adapt this for variant usage.