JSON QT中相同顺序和长度的对象比较

JSON object Comparison in QT of same order and length

我有两个对象,我希望比较并显示两个对象中值的差异。一个是我的参考对象,另一个是我的测试对象。键的顺序,对象的长度都是一样的。我的对象中的整数和浮点值可能略有不同,我希望向用户显示差异。

这是代码,我想知道它们是否会遍历我的对象中的每个值。

if(bool(refobject.length()==testobject.length())==true)
{
QJsonObject::iterator i,j;
for (i = refobject.begin(), j= testobject.begin(); 
              i!=refobject.end()&&j!=testobject.end(); ++i,++j)
{
if(i.key()==j.key())
   {     
   if(i.value().isString() && j.value().isString())
   { 
       if(i.value()==j.value())
       {
         //display i and j
       }
       else 
       {
        //display them in a different colour 
       }

     }
   else if(i.value().isArray()&& j.value().isArray())
   {
     //iterate and compare
   }
   else if(i.value().isObject() && j.value().isObject())
   {
      //check if there are strings or integers or array and work accordingly 
   }
   else if(i.value().isDouble() && j.value().isDouble())
   {
       if(i.value()==j.value())
       {
         //display i and j
       }
       else 
       {
          //display them in a different colour 
       }

   }

}
}
}

else{//display message that you cannot compare them}

我想知道这是否可以帮助我迭代和比较两个对象中的值。

任何其他迭代两个 json 对象并比较值的策略将不胜感激!

提前致谢!!!

我解决了一个类似的问题:只搜索差异(删除、创建和更改的值)并记录这些。我的递归算法适用于 JSON 字符串的所有结构。 基本上,它对对象使用 QJsonObject.keys(),对数组使用 QJsonArray.size() 进行迭代,并检查每个值的差异(它本身是 JsonObject、JsonArray 或 JsonValue)。

JsonComparer.h

#pragma once

#include <qjsondocument.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qstringlist.h>

class JsonComparer {
public:
  QStringList compare(const QString json1, const QString json2);

private:
  void compareObjects(QStringList keyStack, const QJsonObject obj1, const QJsonObject obj2);
  void compareArrays(QStringList keyStack, const QJsonArray arr1, const QJsonArray arr2);
  void compareValues(QStringList keyStack, const QJsonValue val1, const QJsonValue val2);

private:
  QStringList m_differences;
};

JsonComparer.cpp

#include "JsonComparer.h"
#include <qvariant.h>
#include <qdebug.h>

QStringList JsonComparer::compare(const QString json1, const QString json2) {
  m_differences.clear();

  QJsonObject obj1 = QJsonDocument::fromJson(json1.toUtf8()).object();
  QJsonObject obj2 = QJsonDocument::fromJson(json2.toUtf8()).object();
  compareObjects(*(new QStringList()), obj1, obj2);

  return m_differences;
}

void JsonComparer::compareObjects(QStringList keyStack, const QJsonObject obj1, const QJsonObject obj2) {
  QStringList keysObj1 = obj1.keys();
  QStringList keysObj2 = obj2.keys();

  for (QString key : keysObj1) {
    if (!keysObj2.contains(key)) {
      m_differences << keyStack.join(", ") + ", " + key + ": deleted";
    }
  }

  for (QString key : keysObj2) {
    if (!keysObj1.contains(key)) {
      m_differences << keyStack.join(", ") + ", " + key + ": created";
    }
  }

  for (QString key : keysObj1) {
    if (keysObj2.contains(key)) {
      keyStack.append(key);

      if (obj1[key].isArray()) {        
        compareArrays(keyStack, obj1[key].toArray(), obj2[key].toArray());        
      }
      else if (obj1[key].isObject()) {
        compareObjects(keyStack, obj1[key].toObject(), obj2[key].toObject());
      }
      else {
        if (obj1[key] != obj2[key]) {
          compareValues(keyStack, obj1[key], obj2[key]);
        }
      }

      keyStack.removeLast();
    }
  }
}

void JsonComparer::compareArrays(QStringList keyStack, const QJsonArray arr1, const QJsonArray arr2) {
  quint32 minSize = qMin<int>(arr1.size(), arr2.size());

  for (quint32 i = 0; i < minSize; i++) {
    keyStack.append("[" + QString::number(i) + "]");

    if (arr1[i].isArray()) {      
      compareArrays(keyStack, arr1[i].toArray(), arr2[i].toArray());
    }
    else if (arr1[1].isObject()) {
      compareObjects(keyStack, arr1[i].toObject(), arr2[i].toObject());      
    }

    keyStack.removeLast();
  }  

  if (arr1.size() > arr2.size()) {
    for (quint32 i = minSize; i < arr1.size(); i++) {
      m_differences << keyStack.join(", ") + ", " + "[" + QString::number(i) + "]" + ": deleted";
    }
  }

  if (arr1.size() < arr2.size()) {    
    for (quint32 i = minSize; i < arr2.size(); i++) {
      m_differences << keyStack.join(", ") + ", " + "[" + QString::number(i) + "]" + ": created";
    }    
  }
}

void JsonComparer::compareValues(QStringList keyStack, const QJsonValue val1, const QJsonValue val2) {
  if (val1.isString()) {
    m_differences << keyStack.join(", ") + ": changed from " + val1.toString() + " to " + val2.toString();
  }
  else if (val1.isDouble()) {
    m_differences << keyStack.join(", ") + ": changed from " + QString::number(val1.toDouble()) + " to " + QString::number(val2.toDouble());
  }
}

作为示例输出(我不得不取出一些部分):

> Grills, [0]: deleted 
> Grills, [1]: deleted 
> LongName: changed from ... to ... 
> ProductCode: changed from 321 to 474
> RequestId: changed from 34E169A7-1E4E-7695-BA5C-5C277607BA5C to 5B6088D7-AF85-EECB-4D83-61FC179BA18F 
> ShortName: changed from ... to ... 
> attributes, OrderId: changed from 640 to 149 
> attributes, OrderKey: changed from 0006:845097930 to 0001:205422059
> attributes, PodType: changed from 8 to 0 
> attributes, SaleDate: changed from 2019-01-20T13:31:04.1795784Z to 2019-01-20T13:45:46.5153031Z
> attributes, SaleType: changed from 0 to 1