【问题标题】:Find all keys JSON - RapidJSON查找所有键 JSON - RapidJSON
【发布时间】:2019-04-11 09:31:30
【问题描述】:

我需要使用 rapidJSON 库找到 kTypeNames[] 中的所有键。 试图迭代所有节点,但我错过了一些东西;这是代码:

#include <iostream>
#include <fstream>
#include <string>
#include <bits/stdc++.h>
#include <unistd.h>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

using namespace rapidjson;

using namespace std;

const char* kTypeNames[] = { "id", "text", "templ_text", "key" };

int main(int argc, char* argv[]) {

string line;
char json[65000];
std::ifstream file(argv[1]);
unsigned long i = 0;
if (file.is_open()) {
    while (!file.eof()) {
        file.get(json[i]);
        i++;
    }
    file.close();
} else {
    cout << "Unable to open file";
}

Document document;
document.Parse(json);
printf("\n\n\n\n*********Access values in document**********\n");

assert(document.IsObject());

for (auto Typename : kTypeNames) {
    if (document.HasMember(Typename)) {

        cout << "\n";
        cout << Typename << ":" << document[Typename].GetString()<< endl;
        cout << "\n";
    }
    else {
        cout << "\n None\n";
    }
 }

它不适用于嵌套的 JSON。

{
"node": {
    "text": "find this",
    "templ_text": "don't find",
    "ver": "don't find"
},
"ic": "",
"text": "also this",
"templ_text": "don't care",
"par": {
    "SET": {
        "vis": "<blabla>",
        "text": "keyFound",
        "templ_text": "don't need this"
    }
}
}

这是输出:

None
text:also this
templ_text:don't care
None

我想找到所有的“文本”键 如何遍历所有节点/ json 文档?

【问题讨论】:

    标签: c++ rapidjson


    【解决方案1】:

    您的代码只是直接在文档根目录中搜索预定义键的列表(document.HasMember 不是递归搜索!)。

    您可以递归地遍历文档节点。例如,对于对象/地图节点,您在 MemberBegin()MemberEnd() 迭代器上循环,类似于 std::map 或其他标准容器。

    for (auto i = node.MemberBegin(); i != node.MemberEnd(); ++i)
    {
        std::cout << "key: " << i->name.GetString() << std::endl;
        WalkNodes(i->value);
    }
    

    数组使用Begin()End()。然后,当遇到带有“text”成员的节点时,可以输出该节点的值(i-&gt;value)。

    或者,您可以使用解析器流而不是使用Document DOM 对象。 Rapidjson 为此使用“推送”API,它在遇到每个 JSON 片段时调用您在类中定义的方法。具体来说,它会调用一个Key 方法。

    class MyHandler : public BaseReaderHandler<UTF8<>, MyReader> {
        bool Key(const char* str, SizeType length, bool copy)
        {
            std::cout << "Key: " << str << std::endl;
        }
        ...
    };
    MyHandler handler;
    rapidjson::Reader reader;
    rapidjson::StringStream ss(json);
    reader.Parse(ss, handler);
    

    这有点复杂,你会想要设置某种标志,然后输出下一个值回调。

    class MyHandler : public BaseReaderHandler<UTF8<>, MyReader> {
        bool Key(const char* str, SizeType length, bool copy)
        {
            isTextKey = strcmp(str, "text") == 0; // Also need to set to false in some other places
            return true;
        }
        bool String(const char* str, SizeType length, bool copy)
        {
            if (isTextKey) std::cout << "text string " << str << std::endl;
            return true;
        }
        ...
    
        bool isTextKey = false;
    };
    

    还请记住,JSON 允许在字符串 \0 中包含 null,这就是为什么还具有大小参数和成员以及 Unicode 的原因。所以要完全支持任何需要考虑的 JSON 文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多