繁体   English   中英

为了写入jsoncpp(C ++)

[英]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"});

注意:

  • 我将此用于相对较小的对象(配置数据)。
  • 我使用“标签” SORTEDKEY,因为它不会出现在数据中的任何地方。 根据需要进行修改。
  • 我不检查使用的键是否确实存在。 您可以添加此检查。
  • 您还可以使用它来生成原始对象的受限的 ,有序的子集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM