Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找JSON文档中所有值的所有路径_C++_Json_Algorithm - Fatal编程技术网

C++ 查找JSON文档中所有值的所有路径

C++ 查找JSON文档中所有值的所有路径,c++,json,algorithm,C++,Json,Algorithm,对于JSON文档中的每个值,我需要一个指向该值的键序列。换句话说,我正在寻找一种方法来返回包含JSON文档中每个值的所有路径的向量。结果(路径序列)应该是向量,路径应该是JSON键的向量,键应该是字符串 因此,最终结果应该存储在std::vector allpath中 该解决方案可以使用任何JSON解析库,不管该解决方案使用什么依赖项(显然,较少的依赖项和可读代码是首选) JSON文档示例: { "shopper": { "Id": "4973860941232342", "

对于JSON文档中的每个值,我需要一个指向该值的键序列。换句话说,我正在寻找一种方法来返回包含JSON文档中每个值的所有路径的向量。结果(路径序列)应该是向量,路径应该是JSON键的向量,键应该是字符串

因此,最终结果应该存储在
std::vector allpath

该解决方案可以使用任何JSON解析库,不管该解决方案使用什么依赖项(显然,较少的依赖项和可读代码是首选)

JSON文档示例:

{
  "shopper": {
    "Id": "4973860941232342",
    "Context": {
      "CollapseOrderItems": false,
      "IsTest": false
    }
  },
  "SelfIdentifiersData": {
    "SelfIdentifierData": [
      {
        "SelfIdentifierType": {
          "SelfIdentifierType": "111"
        }
      },
      {
        "SelfIdentifierType": {
          "SelfIdentifierType": "2222"
        }
      }
    ]
  }
}
std::vector<std::vector<std::string>> allPaths;                     // container to store the result

allPaths.push_back({"shopper"});                                    // path to an object
allPaths.push_back({"shopper", "Id"});                              // path to string "4973860941232342"
allPaths.push_back({"shopper", "Context"});                         // path to an object
allPaths.push_back({"shopper", "Context", "CollapseOrderItems"});   // path to boolean false
allPaths.push_back({"shopper", "Context", "IsTest"});               // path to boolean false

allPaths.push_back({"SelfIdentifiersData"});                        // path to an object
allPaths.push_back({"SelfIdentifiersData", "SelfIdentifierData"});  // path to an array
示例JSON文档的结果:

{
  "shopper": {
    "Id": "4973860941232342",
    "Context": {
      "CollapseOrderItems": false,
      "IsTest": false
    }
  },
  "SelfIdentifiersData": {
    "SelfIdentifierData": [
      {
        "SelfIdentifierType": {
          "SelfIdentifierType": "111"
        }
      },
      {
        "SelfIdentifierType": {
          "SelfIdentifierType": "2222"
        }
      }
    ]
  }
}
std::vector<std::vector<std::string>> allPaths;                     // container to store the result

allPaths.push_back({"shopper"});                                    // path to an object
allPaths.push_back({"shopper", "Id"});                              // path to string "4973860941232342"
allPaths.push_back({"shopper", "Context"});                         // path to an object
allPaths.push_back({"shopper", "Context", "CollapseOrderItems"});   // path to boolean false
allPaths.push_back({"shopper", "Context", "IsTest"});               // path to boolean false

allPaths.push_back({"SelfIdentifiersData"});                        // path to an object
allPaths.push_back({"SelfIdentifiersData", "SelfIdentifierData"});  // path to an array
到目前为止,我尝试使用解析纯文本json文档,然后使用深度优先搜索(递归+回溯)查找所有路径:

#include <string>
#include <vector>
#include "rapidjson-master/include/rapidjson/document.h"  // single header include for the json parsing library: https://github.com/Tencent/rapidjson#installation

using namespace rapidjson;

// rapidJson uses this to determine the type of the value for a key-value pair
static const char* kTypeNames[] =
        { "Null", "False", "True", "Object", "Array", "String", "Number" };

void dfs(std::vector<std::vector<std::string>> &result, std::vector<std::string> &currPath, const Value &currElement) {

    // add current path to result (create separate copy to avoid modifications of paths that have been added to the result)
    std::vector<std::string> newQuery(currPath);
    result.push_back(newQuery);


    // if current key doesn't have an object (document) as value then we can't go down further so simply return (end current recursive call)
    if (currElement.GetType() != 3) {
        return;
    }


    // iterate all key-value pairs reachable from currPath, for each make one recursive call (add currKey to currPath, modify parsedJsonObj (move down a level at currKey), recurse, backtrack by removing currKey from currPath and by moving back parsedJsonObj)
    for (Value::ConstMemberIterator itr = currElement.MemberBegin(); itr != currElement.MemberEnd(); ++itr) {
        //printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);

        currPath.push_back(itr->name.GetString());

        dfs(result, currPath, itr->value);

        currPath.pop_back();
    }

}

std::vector<std::vector<std::string>> generateAllQueries(std::string &plainTextJson) {

    Document document;
    document.Parse(plainTextJson.c_str());

    std::vector<std::vector<std::string>> result;
    std::vector<std::string> currPath;
    dfs(result, currPath, document);

    return result;
}
#包括
#包括
#include“rapidjson master/include/rapidjson/document.h”//single header include用于json解析库:https://github.com/Tencent/rapidjson#installation
使用名称空间rapidjson;
//rapidJson使用它来确定键值对的值的类型
静态常量char*kTypeNames[]=
{“Null”、“False”、“True”、“Object”、“Array”、“String”、“Number”};
无效dfs(标准::向量和结果,标准::向量和当前路径,常量值和当前元素){
//将当前路径添加到结果(创建单独的副本以避免修改已添加到结果的路径)
std::vector newQuery(currPath);
结果。推回(newQuery);
//若当前键并没有一个对象(文档)作为值,那个么我们就不能再往下走了,所以只需返回(结束当前递归调用)
if(currElement.GetType()!=3){
返回;
}
//迭代可从currPath访问的所有键值对,每次进行一次递归调用(将currKey添加到currPath,修改parsedJsonObj(在currKey处向下移动一个级别),递归,通过从currPath移除currKey并向后移动parsedJsonObj来回溯)
对于(Value::ConstMemberIterator itr=currElement.MemberBegin();itr!=currElement.MemberEnd();++itr){
//printf(“成员%s的类型是%s\n”,itr->name.GetString(),kTypeNames[itr->value.GetType());
currPath.push_back(itr->name.GetString());
dfs(结果、当前路径、itr->值);
currPath.pop_back();
}
}
std::vector generateAllQueries(std::string和plainTextJson){
文件;
Parse(plainTextJson.c_str());
std::向量结果;
向量路径;
dfs(结果、路径、文档);
返回结果;
}
有,但它们使用不同的语言,不返回对象(子文档)的路径


我目前正在完成这项工作,我不知道如何正确地进行重复呼叫。没有rapidjson和完全不同的方法的解决方案是完全好的。唯一的限制是它必须是C++的。所以你想让我们来填你的待办事项?我看不出有什么问题。只要遍历所有叶,如果值相等,则存储到叶的路径。完成。@AnnaVopureta所以问题并不是让这里的人帮你解决问题。目的是就您在尝试中遇到的特定问题寻求帮助。在我看来,你已经有了解决方案的开始(或者基本上是90%),然后你只是中途停了下来,现在你要求其他人完成你开始的工作。这实际上只不过是带有
if
s的一些for循环的递归等价物而已。@AnnaVopureta不幸的是,我还不到10岁。想骗我做作业需要更多的大脑。提示:你可能想要
rapidjson::Value&
而不是
rapidjson::Document&
作为
dfs
啊,
const Value&
的参数。您正在使用常量迭代器。您的方法似乎很好。所以你想让我们来填你的待办事项?我看不出有什么问题。只要遍历所有叶,如果值相等,则存储到叶的路径。完成。@AnnaVopureta所以问题并不是让这里的人帮你解决问题。目的是就您在尝试中遇到的特定问题寻求帮助。在我看来,你已经有了解决方案的开始(或者基本上是90%),然后你只是中途停了下来,现在你要求其他人完成你开始的工作。这实际上只不过是带有
if
s的一些for循环的递归等价物而已。@AnnaVopureta不幸的是,我还不到10岁。想骗我做作业需要更多的大脑。提示:你可能想要
rapidjson::Value&
而不是
rapidjson::Document&
作为
dfs
啊,
const Value&
的参数。您正在使用常量迭代器