c - gSOAP:如何在 C 中比较两个值结构(带有 JSON 内容)?

标签 c json gsoap

我正在将 gSOAP(C 语言)用于客户端应用程序,该应用程序正在调用 Java Web 服务。我正在使用函数 json_call()。 我有一个填充有 JSON 输入数据的请求结构,并且我得到了一个填充有来自 Java 服务的 JSON 输出数据的响应结构。两个 JSON 总体上具有相同的结构,但可以包含更多、更少或更改的元素。

我现在的任务是找出响应与请求不同的元素。主要元素是一个包含很多成员的大数组,例如:

{
    "objects": [
    {
        "@id": "OBJ00001",
        "name": "value",
        ...
    },
    {
        "@id": "OBJ00002",
        "number": 123,
        ...
    },
    ...
    ]
}

我可以使用 @id 字段识别任何同类对象。

使用以下内容迭代 objects 数组很简单:

for(i = 0; i < has_size(value_at(response, "objects")); i++)

但是我缺少一个函数,它可以将请求和响应中具有相同@id的成员(“对象”)进行比较。类似“findMemberWithSameField”然后“equal”(两者都不存在!):

struct member *currentMemberInResponse = NULL;
struct member *memberWithSameField     = NULL;

for(i = 0; i < has_size(value_at(response, "objects")); i++)
{
    /* get the current member out of the response array */
    currentMemberInResponse = nth_value(value_at(response, "objects"), i);

    /* Find member/object with same @id in request */
    memberWithSameField = findMemberWithSameField(value_at(request, "objects"), currentMemberInResponse , "@id"));

    /* equal is true if all fields are the same */
    if(equal(currentMemberInResponse, memberWithSameField))
    {
        /* Do nothing, because nothing changed */
    }
    else
    {
        /* Do something */
    }
}

对这项任务有什么想法吗?否则我必须编写自己的“findMemberWithSameField”和“euqal”。

亲切的问候丹尼尔

最佳答案

JSON C++ API 定义operator== 来递归比较两个对象。最新版本 2.8.55 可以(我已经测试过)比较两个 JSON 对象,其中 operator== 调用以下函数:

bool json_eqv(const value& x, const value& y)
{
  ...
  switch (x.__type)
  {
    ...
    case SOAP_TYPE__struct:
      if (x.size() != y.size())
        return false;
      else
      {
        const _struct& s = x;
        const _struct& t = y;
        for (_struct::iterator i = s.begin(); i != s.end(); ++i)
        {
          _struct::iterator j;
          for (j = t.begin(); j != t.end(); ++j)
            if (!strcmp(i.name(), j.name()))
              break;
          if (j == t.end() || *i != *j)
            return false;
        }
        return true;
      }

这可以重写为 C 语言,如下所示:

int json_eqv(const value *x, const value *y)
{
  if (x->__type != y->__type &&
      (x->__type != SOAP_TYPE__i4 || y->__type != SOAP_TYPE__int) &&
      (x->__type != SOAP_TYPE__int || y->__type != SOAP_TYPE__i4))
    return false;
  switch (x->__type)
  {
    case SOAP_TYPE__boolean:
    case SOAP_TYPE__i4:
    case SOAP_TYPE__int:
      return int_of(x) == int_of(y);
    case SOAP_TYPE__double:
      return double_of(x) == double_of(y);
    case SOAP_TYPE__string:
    case SOAP_TYPE__dateTime_DOTiso8601:
      return !strcmp(string_of(x), string_of(y));
    case SOAP_TYPE__struct:
      if (has_size(x) != has_size(y))
        return 0;
      else
      {
        size_t i, j;
        for (i = 0; i < has_size(x); ++i)
        {
          for (j = 0; j < has_size(y); ++j)
            if (!strcmp(nth_member(x, i), nth_member(y, j))
              break;
          if (j == has_size(y) || !json_eqv(nth_value(x, i), nth_value(y, j))
            return 0;
        }
        return 1;
      }
    case SOAP_TYPE__array:
      if (has_size(x) != has_size(y))
        return 0;
      else
      {
        int i;
        for (i = 0 ; i < has_size(x); ++i)
          if (!json_eqv(nth_nth(x, i), nth_nth(y, i))
            return 0;
        return 1;
      }
    default:
      return 0;
  }
}

关于c - gSOAP:如何在 C 中比较两个值结构(带有 JSON 内容)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46367772/

相关文章:

使用mutex_lock、cond_wait的C pthread编程(计算素数)

C:什么是在读取字符串时对整个 ascii 表进行频率计数(尽可能接近)的可读方法

c - 维吉尼亚密码C语言

c - 生产者消费者C中的段错误

javascript - 将服务器端 json 与 Highchart 结合使用

javascript - 从外部 JavaScript 访问 JSON 数据

javascript - 如何在带有 Handlebars 的 json 文件中获取对象键

c++ - C++ 的 Web 服务客户端库

c++ - gSOAP 动态数组作为输入参数

c++ - 将 gSOAP 与 2 个不同的 wsdl 文件一起使用时出现链接器错误