[英]Writing in order to jsoncpp (c++)
考虑以下示例,我的来源是
Json::Value root;
root["id"]=0;
Json::Value text;
text["first"]="i";
text["second"]="love";
text["third"]="you";
root["text"]=text;
root["type"]="test";
root["begin"]=1;
root["end"]=1;
Json::StyledWriter writer;
string strJson=writer.write(root);
cout<<"JSON WriteTest" << endl << strJson <<endl;
我以为我会按照行的顺序写json字段。 相反,结果是:
JSON WriteTest
{
"begin" : 1,
"end" : 1,
"id" : 0,
"text" : {
"first" : "i",
"second" : "love",
"third" : "you"
},
"type" : "test"
}
我想要json格式是
JSON WriteTest
{
"id" : 0,
"text" : {
"first" : "i",
"second" : "love",
"third" : "you"
},
"type" : "test"
"begin" : 1,
"end" : 1,
}
我该如何写杰森订单?
不,我认为你不能。 JsonCpp将其值保存在std::map<CZString, Value>
,该值始终通过CZString比较进行排序。 因此,它不知道您添加项目的原始顺序。
我有办法可以解决您的问题。 你想试一下吗? 我的解决方案是您使用boost/property_tree/json_parser.hpp
,输出是您想要的格式! 关于有我的代码:
#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
boost::property_tree::ptree parser, child;
parser.put("id", 0);
child.put("first", "i");
child.put("second", "love");
child.put("third", "you");
parser.put_child("text", child);
parser.put("type", "test");
parser.put("begin", 1);
parser.put("end", 1);
stringstream ss;
boost::property_tree::json_parser::write_json(ss, parser);
cout << ss.str() << endl;
return 0;
}
在运行代码之前,您应该安装boost 1.57。 代码在gcc 4.7中运行良好,提升了1.57。输出为{“ id”:0,“ text”:{“ first”:“ i”,“ second”:“ love”,“ third”:“ you”} ,“ type”:“ test”“ begin”:1,“ end”:1,}。 关于boost::property_tree::ptree
,您可以点击这里 。 它使用list<pair<key, ptree>>
保存数据。 因此它保存了无序数据,除非您调用list.sort()
。 希望对您有所帮助。
这是我从jsoncpp获取有序json输出的解决方法
Json::Value root;
root["*1*id"]=0;
Json::Value text;
text["*1*first"]="i";
text["*2*second"]="love";
text["*3*third"]="you";
root["*2*text"]=text;
root["*3*type"]="test";
root["*4*begin"]=1;
root["*5*end"]=1;
Json::StyledWriter writer;
string resultString=writer.write(root);
resultString=ReplaceAll(resultString,"*1*", "");
resultString=ReplaceAll(resultString,"*2*", "");
resultString=ReplaceAll(resultString,"*3*", "");
resultString=ReplaceAll(resultString,"*4*", "");
resultString=ReplaceAll(resultString,"*5*", "");
cout<<"JSON WriteTest" << endl << resultString <<endl;
与RepleceAll函数定义为此
std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}
对象中的键/值对将始终进行排序。 Json数组未排序,它们由一系列没有键的值组成。 作为数组中括号内的键-值对的命名集合(数组)的对象将保留其位置,例如
{
"adressen" : [
{
"start" : {
"ID" : 1,
"key" : "2352KJ25",
"lat" : 52.157225922529967,
"lon" : 4.5298663828345527
}
},
{
"eind" : {
"ID" : 2,
"key" : "2352KJ25",
"lat" : 52.157225922529967,
"lon" : 4.5298663828345527
}
}
}
ID,键,lat,lon被排序,但是start和eind处于其原始位置。 因此,至少您的第一,第二,第三名可能是
Json::Value text(Json::arrayValue);
text.append("I");
text.append("love");
text.append("you");
不需要标签第一,第二和第三! 也许这可以帮助您找到解决方法。
如The Dark所述 , JsonCpp将其值保存在std::map<CZString, Value>
,该值始终按CZString
比较进行排序,而不会跟踪添加项目的原始顺序或所需的顺序输出。
但是,您可以使用此“隐藏功能”以使自己受益。 我的意思是,您只需CZString
所需顺序的键遵循CZString
的“自然”顺序CZString
。 我的JSONCPP包装器类中有一个执行此操作的方法。 将Quick'n'dirty代码转换为简单函数将是这样的:
std::string sortedStr(Json::Value & value, std::vector<std::string> sortKeys)
{
Json::Value sortedValue; // The JSON object to store the new (sorted) hash
char newKey[60]; // I use C expressions, modify to C++ if you like
// Build new sortedValue
int i = 0;
for (auto & key : sortKeys) {
sprintf(newKey, "SORTEDKEY:%03d-%s", i++, key.c_str());
sortedValue[newKey] = value[key];
}
// Write to string, should be sorted on primary keys
Json::StyledWriter w;
std::string result = w.write(sortedValue);
// Remove aux. tags from primary keys
std::size_t pos = 0;
while ((pos = result.find("SORTEDKEY:", pos)) != std::string::npos) {
result.erase(pos, 14);
}
return result;
}
要使用它,只需调用:
std::string sortedObjStr = sortedValue(myValue, {"first", "second", "third", "fourth"});
注意:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.