首页 > 解决方案 > 如何评估 JSON 的键以匹配特定键并提取该键的值?

问题描述

我有一个非常复杂的 JSON 结构,其中嵌套了 JSON 和数组。从那里我想获取一个带有关键元数据的对象(json)。JSON的顺序不是每次都固定的。我如何获取该 JSON 的值?这是示例 json 结构

{
"id": "*******",
"name": "createNewApiKey",
"start_time": 1543504061.474,
"end_time": 1543504062.059,
"parent_id": "******",
"aws": {
    "function_arn": "********",
    "resource_names": [
        "****"
    ],
    "account_id": "******"
},
"trace_id": "1-5c0000bc-*****",
"origin": "AWS::Lambda::Function",
"subsegments": [
    {
        "id": "5d680f995ca8cfd9",
        "name": "*******",
        "start_time": 1543504061.503,
        "end_time": 1543504061.977,
        "fault": true,
        "error": true,
        "cause": {
            "exceptions": [
                {
                    "stack": [
                        {
                            "path": "/var/task/node_modules/aws-xray-sdk-core/lib/patchers/aws_p.js",
                            "line": 77,
                            "label": "captureAWSRequest [as customRequestHandler]"
                        },
                        {
                            "path": "/var/runtime/node_modules/aws-sdk/lib/service.js",
                            "line": 267,
                            "label": "addAllRequestListeners"
                        },
                        {
                            "path": "/var/runtime/node_modules/aws-sdk/lib/service.js",
                            "line": 191,
                            "label": "makeRequest"
                        },
                        {
                            "path": "/var/runtime/node_modules/aws-sdk/lib/service.js",
                            "line": 499,
                            "label": "svc.anonymous function [as getSecretValue]"
                        },
                        {
                            "path": "/var/task/index.js",
                            "line": 34,
                            "label": "exports.handler"
                        }
                    ],
                    "message": "*****",
                    "type": "ResourceNotFoundException",
                    "remote": true
                }
            ],
            "working_directory": "/var/task"
        },
        "http": {
            "response": {
                "status": 400
            }
        },
        "aws": {
            "operation": "GetSecretValue",
            "region": "eu-west-1",
            "request_id": "******",
            "retries": 0
        },
        "namespace": "aws",
        "subsegments": [
            {
                "id": "*****",
                "name": "Metadata",
                "start_time": 1543504061.981,
                "end_time": 1543504062.017,
                "metadata": {
                    "default": {
                        "inputData": {
                            "clientName": "a",
                            "productOwner": "dev"
                        },
                        "response": "Wrong client ID"
                    }
                }
            }
        ]
    },
    {
        "id": "********",
        "name": "Initialization",
        "start_time": 1543504060.726,
        "end_time": 1543504061.47,
        "aws": {
            "*****"
        }
    },
    {
        "id": "********",
        "name": "annotations",
        "start_time": 1543504061.477,
        "end_time": 1543504061.478,
        "annotations": {
            "User": "dev",
            "Name": "a"
        }
    }
]

}

** 可能包含 JSON 或数组

这里我想在JSON下面获取

{
                          "inputData": {
                            "id": "*****",
                            "givenClientName": "abc1012",
                            "productOwner": "dev"
                          },
                          "response": "** successfully"
                        }

标签: javascriptnode.jsjsonamazon-web-services

解决方案


您需要一个递归搜索功能。

以下 ES6 片段递归遍历obj中的所有节点,直到找到key的出现。

它不假定包含数组的节点用“子段”标识。但是您可以k == 'subsegments' && Array.isArray(obj[k])执行此规则。

search = (obj, key) => {
  let res = null;

  (searchNode = obj => Object.keys(obj).some(k => {
    if(k == key) {
      res = obj[k];
      return true;
    }
    return Array.isArray(obj[k]) && obj[k].some(searchNode);
  }))(obj);

  return res;
}

obj = {
  "id": "*******",
  "name": "createNewApiKey",
  "start_time": 1543504061.474,
  "end_time": 1543504062.059,
  "parent_id": "******",
  "subsegments": [
    {
      "subsegments": [
        {
          "subsegments": [
            {
              "subsegments": [
                {
                  "metadata": {
                    "default": {
                      "inputData": {
                        "id": "*****",
                        "givenClientName": "abc1012",
                        "productOwner": "dev"
                      },
                      "response": "** successfully"
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

console.log(search(obj, 'metadata'))


推荐阅读