我需要使用 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/