我需要使用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
我想找到所有的“文本”键 我该如何遍历所有的nodes / json文档?
答案 0 :(得分: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()
。然后,当遇到带有“文本”成员的节点时,可以输出该节点的值(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
中使用null,这就是为什么还具有size参数和成员以及Unicode的原因。因此,要完全支持任何需要考虑的JSON文档。