C++提取JSON文档所有值的键路径方案技术问询
Requirement
Extract the set of key paths for each value in a JSON document, storing the final result in a std::vector<std::vector<std::string>> named allPaths. Each path is a vector of strings composed of JSON keys. Important: Do not include paths to array elements, only the path to the array itself.
Example
Sample JSON Document
{ "shopper": { "Id": "4973860941232342", "Context": { "CollapseOrderItems": false, "IsTest": false } }, "SelfIdentifiersData": { "SelfIdentifierData": [ { "SelfIdentifierType": { "SelfIdentifierType": "111" } }, { "SelfIdentifierType": { "SelfIdentifierType": "2222" } } ] } }
Expected Result
std::vector<std::vector<std::string>> allPaths; // Result container allPaths.push_back({"shopper"}); // Object path allPaths.push_back({"shopper", "Id"}); // String value path allPaths.push_back({"shopper", "Context"}); // Object path allPaths.push_back({"shopper", "Context", "CollapseOrderItems"}); // Boolean value path allPaths.push_back({"shopper", "Context", "IsTest"}); // Boolean value path allPaths.push_back({"SelfIdentifiersData"}); // Object path allPaths.push_back({"SelfIdentifiersData", "SelfIdentifierData"}); // Array path
Current Attempt
I'm using RapidJson to parse the JSON and trying to extract paths via DFS recursive backtracking, but there's a flaw in the recursive logic that prevents the implementation from being complete. Any C++ JSON parsing library is acceptable for the solution.
Existing Code
#include <string> #include <vector> #include "rapidjson-master/include/rapidjson/document.h" using namespace rapidjson; // RapidJson type name array for checking value types 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) { // Copy current path and add to result to avoid modification affecting stored paths std::vector<std::string> newQuery(currPath); result.push_back(newQuery); // If current element is not an object, stop traversing down if (currElement.GetType() != 3) { return; } // Iterate all key-value pairs of current object, recurse on child nodes and backtrack 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; }
Need Help
I'm looking for a fix to the recursive logic in the DFS function, or any alternative feasible implementation in C++ that meets the requirement.
内容的提问来源于stack exchange,提问作者PlsWork

