从嵌套数组JSON中提取关键内容使用cJSON

huangapple go评论63阅读模式
英文:

Extracting Key from nested array JSON using cJSON

问题

我需要从嵌套的数组JSON中提取关键信息。
嵌套的C JSON

{
  "SDCERR": 0, "InfoMsg": "", "count": 18, 
  "connections": {
    "b59519e0-917d-4c29-b31a-81e1837bd43e": {"activated": 0, "id": "PEAP_GTC_NO_CA_CERT", "type": ""},
    "518b71d4-28ca-41c5-abb6-88245f0bf3fb": {"activated": 0, "id": "Manoj", "type": ""},
    "91988884-d524-43a2-b255-88817330fd8b": {"activated": 0, "id": "NaveedP", "type": ""},
    "26dfa985-cea3-4138-b03e-ab25f96e1dbb": {"activated": 0, "id": "PEAP_MSCHAPv2_NO_CA_CERT", "type": ""},
    "0d82d7d3-a00a-45e3-a42b-66b13afc03f5": {"activated": 0, "id": "PEAP_MSCHAPv2_CA_CERT", "type": ""},
    "1bb69f6c-d75e-44ad-a6ee-de7a5095b57e": {"activated": 0, "id": "EAP_TLS_NO_CA_CERT", "type": ""},
    "566d673a-b48b-4e82-aaa5-724c61ed54c0": {"activated": 0, "id": "nagaveni", "type": ""},
    "9f382a6d-8e3e-4a7e-88e3-33f0b885dcd0": {"activated": 0, "id": "EAP_TTLS_NO_CA_CERT", "type": ""},
    "8284b1b8-a268-4a99-88e4-fdf35f6badb0": {"activated": 0, "id": "PSK", "type": ""},
    "7af2a874-4042-47e5-8065-4ed499901968": {"activated": 0, "id": "EAP_TTLS_CA_CERT", "type": ""},
    "3e622df0-cbd4-4660-afdd-d7b813a2f130": {"activated": 0, "id": "MANOJ-5G", "type": ""},
    "bd89b41c-5688-3e79-8353-f7391d8e5ce9": {"activated": 0, "id": "br-slave-wlan0", "type": ""},
    "cb116408-6a95-42d0-add8-8b40bdd3b4cd": {"activated": 0, "id": "PEAP_GTC_CA_CERT", "type": ""},
    "a99477b4-2ccd-42dc-909d-2c913851be2a": {"activated": 0, "id": "nagaveni 1", "type": ""},
    "a33750a5-3623-49b4-b784-97d718acc959": {"activated": 0, "id": "find", "type": ""},
    "54e7567b-505a-4d29-ba36-533bd2cf25dd": {"activated": 0, "id": "PEAP_WPA3_CA-cert", "type": ""},
    "e5018996-4c3d-4caa-bd08-2dfc4424f520": {"activated": 0, "id": "wireless@telxsids.net", "type": ""},
    "aa616959-ba9f-4ad4-bf5e-4eab629c5d58": {"activated": 1, "id": "internal-usb0"}
  }
}

在这里,我需要通过引用id来获取UUID的值。

例如:if(id == "PSK")
获取UUID: 8284b1b8-a268-4a99-88e4-fdf35f6badb0

请帮我解析嵌套的cJSON。

使用cJSON * deviceData = cJSON_GetObjectItem(root,"connections");函数进行了尝试,但无法获取特定的字符串。

英文:

I need to extract key form nested Array JSON .
Nested C jOSN

{
"SDCERR": 0, "InfoMsg": "", "count": 18, 
"connections": {
"b59519e0-917d-4c29-b31a-81e1837bd43e": {"activated": 0, "id": "PEAP_GTC_NO_CA_CERT", "type": ""},
"518b71d4-28ca-41c5-abb6-88245f0bf3fb": {"activated": 0, "id": "Manoj", "type": ""},
"91988884-d524-43a2-b255-88817330fd8b": {"activated": 0, "id": "NaveedP", "type": ""},
"26dfa985-cea3-4138-b03e-ab25f96e1dbb": {"activated": 0, "id": "PEAP_MSCHAPv2_NO_CA_CERT", "type": ""},
"0d82d7d3-a00a-45e3-a42b-66b13afc03f5": {"activated": 0, "id": "PEAP_MSCHAPv2_CA_CERT", "type": ""},
"1bb69f6c-d75e-44ad-a6ee-de7a5095b57e": {"activated": 0, "id": "EAP_TLS_NO_CA_CERT", "type": ""},
"566d673a-b48b-4e82-aaa5-724c61ed54c0": {"activated": 0, "id": "nagaveni", "type": ""},
"9f382a6d-8e3e-4a7e-88e3-33f0b885dcd0": {"activated": 0, "id": "EAP_TTLS_NO_CA_CERT", "type": ""},
"8284b1b8-a268-4a99-88e4-fdf35f6badb0": {"activated": 0, "id": "PSK", "type": ""},
"7af2a874-4042-47e5-8065-4ed499901968": {"activated": 0, "id": "EAP_TTLS_CA_CERT", "type": ""},
"3e622df0-cbd4-4660-afdd-d7b813a2f130": {"activated": 0, "id": "MANOJ-5G", "type": ""},
"bd89b41c-5688-3e79-8353-f7391d8e5ce9": {"activated": 0, "id": "br-slave-wlan0", "type": ""},
"cb116408-6a95-42d0-add8-8b40bdd3b4cd": {"activated": 0, "id": "PEAP_GTC_CA_CERT", "type": ""},
"a99477b4-2ccd-42dc-909d-2c913851be2a": {"activated": 0, "id": "nagaveni 1", "type": ""},
"a33750a5-3623-49b4-b784-97d718acc959": {"activated": 0, "id": "find", "type": ""},
"54e7567b-505a-4d29-ba36-533bd2cf25dd": {"activated": 0, "id": "PEAP_WPA3_CA-cert", "type": ""},
"e5018996-4c3d-4caa-bd08-2dfc4424f520": {"activated": 0, "id": "wireless@telxsids.net", "type": ""},
"aa616959-ba9f-4ad4-bf5e-4eab629c5d58": {"activated": 1, "id": "internal-usb0"}
}}

Here, by refering id I need get the value of UUID

Example: if(id =="PSK")
get the UUID :8284b1b8-a268-4a99-88e4-fdf35f6badb0.

Please help me how parse the nested cJSON.

Using cJSON * deviceData = cJSON_GetObjectItem(root,"connections"); function I tried, but unable to get the particular string.

答案1

得分: 0

使用cJSON_ArrayForEach(element, array)宏来迭代数组或对象的元素并查找匹配项。对于对象,element中的cJSON指针的string成员是当前元素的名称。

示例程序:

#include <cjson/cJSON.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

// 用于将JSON文件解析为cJSON结构的实用函数
cJSON *parse_json_file(const char *filename) {
  int fd = open(filename, O_RDONLY);

  if (fd < 0) {
    return NULL;
  }

  struct stat st;
  if (fstat(fd, &st) < 0) {
    perror("fstat");
    close(fd);
    return NULL;
  }

  char *buffer = malloc(st.st_size);
  if (!buffer) {
    close(fd);
    return NULL;
  }
  if (read(fd, buffer, st.st_size) != st.st_size) {
    // 读取不完整,将其视为错误处理
    perror("read");
    close(fd);
    free(buffer);
    return NULL;
  }
  close(fd);

  cJSON *cj = cJSON_ParseWithLength(buffer, st.st_size);
  free(buffer);

  return cj;
}

int main(int argc, char **argv) {
  if (argc != 3) {
    fprintf(stderr, "Usage: %s FILENAME ID\n", argv[0]);
    return EXIT_FAILURE;
  }

  cJSON *cj = parse_json_file(argv[1]);
  if (!cj) {
    fprintf(stderr, "无法读取和解析 '%s'。\n", argv[1]);
    return EXIT_FAILURE;
  }

  // 提取 .connections。注意:始终使用区分大小写版本的函数
  cJSON *connections = cJSON_GetObjectItemCaseSensitive(cj, "connections");
  if (!connections) {
    fputs("JSON没有connections关键字。\n", stderr);
    return EXIT_FAILURE;
  }
  if (!cJSON_IsObject(connections)) {
    fputs("JSON connections值不是对象\n", stderr);
    return EXIT_FAILURE;
  }

  // 迭代 .connections 对象的元素
  const char *id = argv[2];
  cJSON *conn;
  cJSON_ArrayForEach(conn, connections) {
    // 对于每个元素的值,查看它是否是具有匹配id字段的对象
    if (cJSON_IsObject(conn)) {
      cJSON *json_id = cJSON_GetObjectItemCaseSensitive(conn, "id");
      if (json_id && cJSON_IsString(json_id) &&
          strcmp(json_id->valuestring, id) == 0) {
        // conn->string 是当前元素的键
        printf("UUID: %s\n", conn->string);
      }
    }
  }

  cJSON_Delete(cj);

  return 0;
}

用法:

$ gcc -g -O -Wall -Wextra example.c -lcjson
$ ./a.out input.json PSK
UUID: 8284b1b8-a268-4a99-88e4-fdf35f6badb0
英文:

Use the cJSON_ArrayForEach(element, array) macro to iterate over the elements of an array or object and look for a match. For objects, the element cJSON pointer's string member is the name of the current element.

Example program:

#include &lt;cjson/cJSON.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;unistd.h&gt;

// Utility function to read a JSON file into a cJSON struct
cJSON *parse_json_file(const char *filename) {
  int fd = open(filename, O_RDONLY);

  if (fd &lt; 0) {
    return NULL;
  }

  struct stat st;
  if (fstat(fd, &amp;st) &lt; 0) {
    perror(&quot;fstat&quot;);
    close(fd);
    return NULL;
  }

  char *buffer = malloc(st.st_size);
  if (!buffer) {
    close(fd);
    return NULL;
  }
  if (read(fd, buffer, st.st_size) != st.st_size) {
    // Incomplete read; treat as an error
    perror(&quot;read&quot;);
    close(fd);
    free(buffer);
    return NULL;
  }
  close(fd);

  cJSON *cj = cJSON_ParseWithLength(buffer, st.st_size);
  free(buffer);

  return cj;
}

int main(int argc, char **argv) {
  if (argc != 3) {
    fprintf(stderr, &quot;Usage: %s FILENAME ID\n&quot;, argv[0]);
    return EXIT_FAILURE;
  }

  cJSON *cj = parse_json_file(argv[1]);
  if (!cj) {
    fprintf(stderr, &quot;Unable to read and parse &#39;%s&#39;.\n&quot;, argv[1]);
    return EXIT_FAILURE;
  }

  // Extract .connections. Note: Always use the CaseSensitive versions of functions
  cJSON *connections = cJSON_GetObjectItemCaseSensitive(cj, &quot;connections&quot;);
  if (!connections) {
    fputs(&quot;JSON has no connections key.\n&quot;, stderr);
    return EXIT_FAILURE;
  }
  if (!cJSON_IsObject(connections)) {
    fputs(&quot;JSON connections value isn&#39;t an object\n&quot;, stderr);
    return EXIT_FAILURE;
  }

  // Iterate over the elements of the .connections object
  const char *id = argv[2];
  cJSON *conn;
  cJSON_ArrayForEach(conn, connections) {
    // For each element&#39;s value, see if it&#39;s object with a matching id field
    if (cJSON_IsObject(conn)) {
      cJSON *json_id = cJSON_GetObjectItemCaseSensitive(conn, &quot;id&quot;);
      if (json_id &amp;&amp; cJSON_IsString(json_id) &amp;&amp;
          strcmp(json_id-&gt;valuestring, id) == 0) {
        // conn-&gt;string is the key of the current element
        printf(&quot;UUID: %s\n&quot;, conn-&gt;string);
      }
    }
  }

  cJSON_Delete(cj);

  return 0;
}

and usage:

$ gcc -g -O -Wall -Wextra example.c -lcjson
$ ./a.out input.json PSK
UUID: 8284b1b8-a268-4a99-88e4-fdf35f6badb0

huangapple
  • 本文由 发表于 2023年6月9日 12:24:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定