C++ 使用JsonCPP库实现根据字符串查找多个JSON 节点并按照层级关系存储
时间: 2024-03-27 13:38:08 浏览: 278
以下是使用 JsonCPP 库实现根据字符串查找多个 JSON 节点并按照层级关系进行存储的示例代码:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "json/json.h"
using namespace std;
void findNodes(Json::Value& root, const string& nodeName, vector<Json::Value*>& nodes) {
if (root.isArray()) {
for (int i = 0; i < root.size(); i++) {
findNodes(root[i], nodeName, nodes);
}
}
else if (root.isObject()) {
if (root.isMember(nodeName)) {
nodes.push_back(&root[nodeName]);
}
for (Json::ValueIterator it = root.begin(); it != root.end(); it++) {
findNodes(*it, nodeName, nodes);
}
}
}
Json::Value* getNodeByPath(Json::Value& root, vector<string>& path) {
if (path.empty()) {
return &root;
}
string nodeName = path[0];
path.erase(path.begin());
if (root.isArray()) {
int index = stoi(nodeName);
if (index < root.size()) {
return getNodeByPath(root[index], path);
}
}
else if (root.isObject()) {
if (root.isMember(nodeName)) {
return getNodeByPath(root[nodeName], path);
}
}
return nullptr;
}
void storeNodes(Json::Value& root, vector<Json::Value*>& nodes, vector<string>& path, Json::Value& result) {
if (nodes.empty()) {
return;
}
string nodeName = path.empty() ? "" : path.back();
path.pop_back();
Json::Value& node = *nodes.back();
nodes.pop_back();
if (path.empty()) {
if (nodeName.empty()) {
result.append(node);
}
else {
result[nodeName] = node;
}
}
else {
Json::Value& parent = *getNodeByPath(result, path);
if (parent.isArray()) {
int index = stoi(nodeName);
if (index >= parent.size()) {
parent.resize(index + 1);
}
storeNodes(parent[index], nodes, path, result);
}
else if (parent.isObject()) {
storeNodes(parent[nodeName], nodes, path, result);
}
}
}
int main() {
// 读取 JSON 文件
ifstream file("data.json");
string jsonStr((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
file.close();
// 解析 JSON 字符串
Json::Value root;
Json::CharReaderBuilder builder;
Json::CharReader* reader = builder.newCharReader();
string errors;
bool success = reader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.size(), &root, &errors);
delete reader;
if (!success) {
cout << "Failed to parse JSON: " << errors << endl;
return 1;
}
// 查找节点
string nodeName = "id";
vector<Json::Value*> nodes;
findNodes(root, nodeName, nodes);
// 存储节点
Json::Value result(Json::arrayValue);
for (Json::Value* node : nodes) {
vector<string> path;
for (Json::Value* parent = node; parent != &root; parent = parent->getParent()) {
path.insert(path.begin(), parent->isObject() ? parent->getMemberName(0) : to_string(parent->getIndex()));
}
storeNodes(root, vector<Json::Value*>({ node }), path, result);
}
// 输出结果
Json::StreamWriterBuilder writerBuilder;
writerBuilder["indentation"] = "\t";
unique_ptr<Json::StreamWriter> writer(writerBuilder.newStreamWriter());
writer->write(result, &cout);
return 0;
}
```
在上述代码中,我们首先使用 `Json::CharReader` 类将 JSON 文件解析为 JsonCPP 的 `Value` 对象。然后我们使用 `findNodes()` 函数查找指定节点名称的所有节点,并将其存储到一个 `vector` 中。我们使用 `getNodeByPath()` 函数根据节点路径获取节点对象。最后,我们使用 `storeNodes()` 函数将节点按照层级关系进行存储,存储结果保存在一个 `Json::Value` 对象中,并使用 `Json::StreamWriter` 类将存储结果输出到控制台。
需要注意的是,上述代码中的 `findNodes()` 函数只能查找对象中的节点,而不能查找数组中的节点。如果需要查找数组中的节点,可以将 `findNodes()` 函数修改为递归遍历整个 JSON 树。此外,上述代码还没有进行错误处理,例如当节点路径不存在时,`getNodeByPath()` 函数会返回 `nullptr`,需要在调用该函数时进行判断。
阅读全文
相关推荐
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20210720083447.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20210720083447.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045021.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)