c++ - 查找所有键 JSON - RapidJSON

标签 c++ rapidjson

我需要使用 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 文档?

最佳答案

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

您可以递归地遍历文档节点。例如,对于对象/ map 节点,您可以在 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()。然后,当你遇到一个有“文本”成员的节点时,你可以输出那个节点的值(i->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 中存在空值,这就是为什么还具有大小参数和成员以及 Unicode 的原因。因此要完全支持任何需要记帐的 JSON 文档。

关于c++ - 查找所有键 JSON - RapidJSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55629185/

相关文章:

c# - 空间坐标的 3D 数组

c++ - C++向下转换期间的内存布局

c++ - 如何让用户设置 2D Vector 的行大小和列大小?

c++ - 作为成员变量的 Rapidjson 文档使该应用程序崩溃

c++ - 更快的 JsonCpp 替代方案允许 Json 对象的复制/可变性?

c++ - 是否可以在需要字符串文字时使用 std::string::c_str() ?

c++ - 制作头文件时遇到问题

c++ - 从 C++ 使用 Neo4j 数据库

rapidjson - 从 JSON 字符串创建 rapidjson::Value

c++ - 如何使用rapidjson合并两个json文件