#include "nmDataJsonTools.h" #include #include // 确保包含这些,以防万一 #include #include // 用于调试输出 // RapidJSON 内部使用 char*,这里需要转换为 std::string #include #include #include #include #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/prettywriter.h" // For pretty printing JSON #include "rapidjson/stringbuffer.h" using namespace rapidjson; // 辅助函数:将 QVariant 递归转换为 rapidjson::Value // 这是最重要的部分,因为它将处理 QVariant 中的嵌套结构 rapidjson::Value QVariantToRapidjsonValue(const QVariant& qv, rapidjson::Document::AllocatorType& allocator) { if (qv.type() == QVariant::Int) { return rapidjson::Value(qv.toInt()); } else if (qv.type() == QVariant::Double) { return rapidjson::Value(qv.toDouble()); } else if (qv.type() == QVariant::String) { return rapidjson::Value(qv.toString().toStdString().c_str(), allocator); } else if (qv.type() == QVariant::Bool) { return rapidjson::Value(qv.toBool()); } else if (qv.type() == QVariant::List) { rapidjson::Value arr(rapidjson::kArrayType); QVariantList list = qv.toList(); for (int i = 0; i < list.size(); ++i) { arr.PushBack(QVariantToRapidjsonValue(list.at(i), allocator), allocator); } return arr; } else if (qv.type() == QVariant::Map) { rapidjson::Value obj(rapidjson::kObjectType); QVariantMap map = qv.toMap(); // Qt4 QMapIterator QMapIterator i(map); while (i.hasNext()) { i.next(); rapidjson::Value key(i.key().toStdString().c_str(), allocator); obj.AddMember(key, QVariantToRapidjsonValue(i.value(), allocator), allocator); } return obj; } else if (qv.isNull() || qv.type() == QVariant::Invalid) { return rapidjson::Value(rapidjson::kNullType); } // 默认情况或不支持的类型 qDebug() << "Warning: Unsupported QVariant type in QVariantToRapidjsonValue: " << qv.type(); return rapidjson::Value(rapidjson::kNullType); } // 写入json void nmDataJsonTools::jsonAdd(rapidjson::Document& document, QVariant value, QVector path) { Document::AllocatorType& allocator = document.GetAllocator(); Value* current = &document; for (int i = 0; i < path.size(); ++i) { QVariant key_var = path.at(i); // 如果是最后一层路径,设置值 if (i == path.size() - 1) { if (key_var.type() == QVariant::String) { std::string key_str = key_var.toString().toStdString(); const char* key_c_str = key_str.c_str(); // 确保当前节点是对象,以便添加成员 if (!current->IsObject()) { current->SetObject(); // 这一步至关重要,如果 current 不是对象,就把它变成对象 } // 将 QVariant 转换为 rapidjson::Value rapidjson::Value val_to_add = QVariantToRapidjsonValue(value, allocator); if (current->HasMember(key_c_str)) { // 如果存在,替换值 (*current)[key_c_str].CopyFrom(val_to_add, allocator); } else { // 如果不存在,添加新成员 current->AddMember(rapidjson::Value(key_c_str, allocator), val_to_add, allocator); } } else if (key_var.type() == QVariant::Int) { // 最后一层路径是数组索引 int index = key_var.toInt(); if (!current->IsArray()) { current->SetArray(); // 如果当前不是数组,就把它变成数组 } // 确保数组大小足够 while (current->Size() <= index) { current->PushBack(rapidjson::Value(rapidjson::kNullType), allocator); // 用 null 填充 } // 将 QVariant 转换为 rapidjson::Value rapidjson::Value val_to_add = QVariantToRapidjsonValue(value, allocator); (*current)[index].CopyFrom(val_to_add, allocator); } else { qDebug() << "Error: Invalid path component type at end of path (expected string or int)."; } return; // 最后一层路径处理完毕 } // 处理中间路径节点 if (key_var.type() == QVariant::String) { std::string key_str = key_var.toString().toStdString(); const char* key_c_str = key_str.c_str(); if (!current->IsObject()) { current->SetObject(); // 确保当前节点是对象 } if (!current->HasMember(key_c_str)) { // 如果中间路径节点不存在,则创建新的空对象 current->AddMember(rapidjson::Value(key_c_str, allocator), rapidjson::Value(rapidjson::kObjectType).Move(), allocator); } current = &((*current)[key_c_str]); // 移动到下一级 } else if (key_var.type() == QVariant::Int) { int index = key_var.toInt(); if (!current->IsArray()) { current->SetArray(); // 确保当前节点是数组 } // 确保数组大小足够 while (current->Size() <= index) { current->PushBack(rapidjson::Value(rapidjson::kNullType), allocator); // 用 null 填充 } // 检查目标索引处是否是对象或数组。如果不是,就把它变成对象 if (!(*current)[index].IsObject() && !(*current)[index].IsArray()) { (*current)[index].SetObject(); // 默认创建对象,如果需要数组则再处理 } current = &((*current)[index]); // 移动到下一级 } else { qDebug() << "Error: Invalid path component type in jsonAdd (expected string or int)."; return; // 路径不合法,提前退出 } } } // 辅助函数:将 rapidjson::Value 递归转换为 QVariant QVariant RapidjsonValueToQVariant(const rapidjson::Value& rv) { if (rv.IsInt()) { return QVariant(rv.GetInt()); } else if (rv.IsDouble()) { return QVariant(rv.GetDouble()); } else if (rv.IsString()) { return QVariant(rv.GetString()); } else if (rv.IsBool()) { return QVariant(rv.GetBool()); } else if (rv.IsArray()) { QVariantList list; for (rapidjson::SizeType i = 0; i < rv.Size(); ++i) { list.append(RapidjsonValueToQVariant(rv[i])); } return list; } else if (rv.IsObject()) { QVariantMap map; for (rapidjson::Value::ConstMemberIterator itr = rv.MemberBegin(); itr != rv.MemberEnd(); ++itr) { map.insert(itr->name.GetString(), RapidjsonValueToQVariant(itr->value)); } return map; } else if (rv.IsNull()) { return QVariant(); // QVariant() 表示null } // 未知类型或默认处理 qDebug() << "Warning: Unsupported rapidjson::Value type in RapidjsonValueToQVariant: " << rv.GetType(); return QVariant(); } // 读json void nmDataJsonTools::jsonRead(rapidjson::Document &document, QVariant &value, QVector path) { const rapidjson::Value* current = &document; for (int i = 0; i < path.size(); ++i) { QVariant key_var = path.at(i); if (key_var.type() == QVariant::String) { std::string key_str = key_var.toString().toStdString(); const char* key_c_str = key_str.c_str(); if (current->IsObject() && current->HasMember(key_c_str)) { current = &((*current)[key_c_str]); } else { value = QVariant(); // 路径不存在 return; } } else if (key_var.type() == QVariant::Int) { int index = key_var.toInt(); if (current->IsArray() && index >= 0 && index < current->Size()) { current = &((*current)[index]); } else { value = QVariant(); // 索引无效 return; } } else { value = QVariant(); // 无效路径组件 return; } } // 到达路径的末端,将当前值赋给value value = RapidjsonValueToQVariant(*current); } // 将 RapidJSON Document 写入文件 bool nmDataJsonTools::WriteDomToFile(const rapidjson::Document& doc, const QString& filePath) { // 将 RapidJSON Document 转换为字符串 rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); // 使用 PrettyWriter 进行美化输出 doc.Accept(writer); // 将字符串写入文件 QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "Error: Could not open file for writing:" << filePath; return false; } QTextStream out(&file); out << buffer.GetString(); file.close(); return true; } // 从文件读取 JSON 并解析到 RapidJSON Document bool nmDataJsonTools::ReadDomFromFile(const QString& filePath, rapidjson::Document& doc) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Error: Could not open file for reading:" << filePath; return false; } QTextStream in(&file); QString jsonString = in.readAll(); file.close(); // 将 QString 转换为 std::string QByteArray byteArray = jsonString.toUtf8(); std::string stdJsonString = byteArray.constData(); // 解析 JSON 字符串到 RapidJSON Document doc.Parse(stdJsonString.c_str()); if (doc.HasParseError()) { qDebug() << "Error parsing JSON from file:" << filePath << "Error:" << doc.GetParseError(); return false; } return true; }