![](/img/trans.png)
[英]How to read json file using rapidjson and output to std::string?
[英]How to merge two json file using rapidjson
我正在嘗試通過加載兩個json文件來構建文檔。 最后加載的文件具有最高優先級。 在下面的示例中, file B
中的item1.value1
覆蓋了file A
的值。 item1.value2
item2
在file A
中不存在,因此最終文檔僅從file B
文件A中獲取值:
{
level1: {
level2: {
item1: {
value1: 20,
}
}
}
文件B:
{
level1: {
item2{
value1: 50
value2: 60,
}
level2: {
item1:{
value1: 40
value2: 30,
}
}
}
我的目標:
{
level1: {
item2{
value1: 50
value2: 60,
}
level2: {
item1: {
value1: 40,
value2: 30,
}
}
}
當我使用范圍來遍歷Document時,另一個問題是,僅對level1
成員進行了遍歷,如何遍歷整個DOM?
for (auto& m : document.GetObject())
printf("Type of member %s is %s\n",
m.name.GetString(), kTypeNames[m.value.GetType()]);
我想您可以嘗試一下(對我有用):
void mergeObjects(rapidjson::Value &dstObject, rapidjson::Value &srcObject, rapidjson::Document::AllocatorType &allocator)
{
for (auto srcIt = srcObject.MemberBegin(); srcIt != srcObject.MemberEnd(); ++srcIt)
{
auto dstIt = dstObject.FindMember(srcIt->name);
if (dstIt != dstObject.MemberEnd())
{
assert(srcIt->value.GetType() == dstIt->value.GetType());
if (srcIt->value.IsArray())
{
for (auto arrayIt = srcIt->value.Begin(); arrayIt != srcIt->value.End(); ++arrayIt)
{
dstIt->value.PushBack(*arrayIt, allocator);
}
}
else if (srcIt->value.IsObject())
{
mergeObjects(dstIt->value, srcIt->value, allocator);
}
else
{
dstIt->value = srcIt->value;
}
}
else
{
dstObject.AddMember(srcIt->name, srcIt->value, allocator);
}
}
}
//...
rapidjson::Document from;
rapidjson::Document to;
mergeObjects(to, from, to.GetAllocator());
注意,節點類型必須相等。 它還通過串聯而不是替換來合並數組。
您可以使用遞歸遍歷整個DOM模型(如上所述)。
希望能幫助到你。
上面的實現假定srcObject
和dstObject
共享相同的內存,因為它傳遞原始值而不是復制它們。 這意味着當釋放srcObject
時, dstObject
將保存釋放的對象。
我通過復制值來實現它:
bool mergeObjects(rapidjson::Value &dstObject, rapidjson::Value &srcObject, rapidjson::Document::AllocatorType &allocator)
{
for (auto srcIt = srcObject.MemberBegin(); srcIt != srcObject.MemberEnd(); ++srcIt)
{
auto dstIt = dstObject.FindMember(srcIt->name);
if (dstIt == dstObject.MemberEnd())
{
rapidjson::Value dstName ;
dstName.CopyFrom(srcIt->name, allocator);
rapidjson::Value dstVal ;
dstVal.CopyFrom(srcIt->value, allocator) ;
dstObject.AddMember(dstName, dstVal, allocator);
dstName.CopyFrom(srcIt->name, allocator);
dstIt = dstObject.FindMember(dstName);
if (dstIt == dstObject.MemberEnd())
return false ;
}
else
{
auto srcT = srcIt->value.GetType() ;
auto dstT = dstIt->value.GetType() ;
if(srcT != dstT)
return false ;
if (srcIt->value.IsArray())
{
for (auto arrayIt = srcIt->value.Begin(); arrayIt != srcIt->value.End(); ++arrayIt)
{
rapidjson::Value dstVal ;
dstVal.CopyFrom(*arrayIt, allocator) ;
dstIt->value.PushBack(dstVal, allocator);
}
}
else if (srcIt->value.IsObject())
{
if(!mergeObjects(dstIt->value, srcIt->value, allocator))
return false ;
}
else
{
dstIt->value.CopyFrom(srcIt->value, allocator) ;
}
}
}
return true ;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.