首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用jq,如何根据标记属性将OpenAPI 3.0文件分割成块?

使用jq,如何根据标记属性将OpenAPI 3.0文件分割成块?
EN

Stack Overflow用户
提问于 2022-11-13 20:08:01
回答 4查看 53关注 0票数 1

我有一些有挑战性的事情要做(至少对我来说是这样)。这个OpenAPI 3.0文件需要一些基于标记的裁剪(即切成与tags属性中的项一样多的块)。

为了简单起见,本例中有两个标记。因此,属于paths转子部件标签的所有将进入第一个字典项。其他部分将放在第二个字典项下。

以下是输入文件:

代码语言:javascript
复制
{
  "openapi": "3.0.0",
  "info": {
    "description": "PREST APIs for external use.",
    "version": "v1",
    "title": "REST API Doc",
    "contact": {},
    "license": {
      "name": "Public"
    }
  },
  "tags":[
      {
        "name": "Rotor Parts",
        "description": "Rotor Parts API"
      },
      {
        "name": "Cloud Accounts",
        "description": "Plant Locations APIs"
      }
    ],
  "paths": {
    "/access_keys": {
      "get": {
        "tags": [
          "Rotor Parts"
        ],
        "summary": "List Rotor Parts",
        "description": "Returns all rotor parts if you have an Admin role. Returns just your rotor parts if you don't have this role.",
        "operationId": "get-my-rotor-parts",
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RotorPartsResponseModel"
                  }
                }
              }
            }
          },
          "400": {
            "description": "user_inactive_or_not_exist"
          },
          "403": {
            "description": "unauthorized_to_use_rotor_parts"
          },
          "500": {
            "description": "failed_fetch_user_profile"
          }
        }
      },
      "post": {
        "tags": [
          "Rotor Parts"
        ],
        "summary": "Add Rotor Parts",
        "description": "Adds a new rotor part for the current user. If you have API access, you can create up to two rotor parts.",
        "operationId": "add-rotor-parts",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserRotorPartRequestModel"
              }
            }
          },
          "description": "Model user rotor part model",
          "required": true
        },
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateUserAccessKeyResponseModel"
                }
              }
            }
          },
          "400": {
            "description": "invalid_expiry_access_key / already_have_two_access_keys / invalid_access_key_name_length / invalid_access_key_name"
          },
          "403": {
            "description": "unauthorized_to_use_access_keys"
          },
          "409": {
            "description": "duplicate_access_key_name"
          }
        }
      }
    },
    "/account/{accountId}/config/status": {
    "get": {
      "tags": [
        "Cloud Accounts"
      ],
      "summary": "List Account Status Details",
      "description": "Returns a list of Cloud services whose status indicates a warning or error for the given cloud account ID. Includes status details for each listed service.",
      "operationId": "list-cloud-account-status-details",
      "parameters": [
        {
          "name": "accountId",
          "in": "path",
          "description": "Cloud account ID",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "responses": {
        "200": {
          "description": "successful operation",
          "content": {
            "application/json; charset=UTF-8": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CloudAccountConfigStatusView"
                }
              }
            }
          }
        },
        "400": {
          "description": "bad_request"
        },
        "500": {
          "description": "internal_error"
        }
      }
    }
  }
  }
}

这是一个预期的产出:

代码语言:javascript
复制
{
  "tag_RotorParts": {
    "info": "same content here",
    "tags": [
      {
        "name": "Rotor Parts",
        "description": "Rotor Parts API"
      }
    ],
    "paths": {
      "/access_keys": {
        "get": {
          "tags": [
            "Rotor Parts"
          ],
          "summary": "List Rotor Parts",
          "description": "Returns all rotor parts if you have an Admin role. Returns just your rotor parts if you don't have this role.",
          "operationId": "get-my-rotor-parts",
          "responses": {
            "200": {
              "description": "successful operation",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RotorPartsResponseModel"
                    }
                  }
                }
              }
            },
            "400": {
              "description": "user_inactive_or_not_exist"
            },
            "403": {
              "description": "unauthorized_to_use_rotor_parts"
            },
            "500": {
              "description": "failed_fetch_user_profile"
            }
          }
        },
        "post": {
          "tags": [
            "Rotor Parts"
          ],
          "summary": "Add Rotor Parts",
          "description": "Adds a new rotor part for the current user. If you have API access, you can create up to two rotor parts.",
          "operationId": "add-rotor-parts",
          "requestBody": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRotorPartRequestModel"
                }
              }
            },
            "description": "Model user rotor part model",
            "required": true
          },
          "responses": {
            "200": {
              "description": "successful operation",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/CreateUserAccessKeyResponseModel"
                  }
                }
              }
            },
            "400": {
              "description": "invalid_expiry_access_key / already_have_two_access_keys / invalid_access_key_name_length / invalid_access_key_name"
            },
            "403": {
              "description": "unauthorized_to_use_access_keys"
            },
            "409": {
              "description": "duplicate_access_key_name"
            }
          }
        }
      }
    }
  },
  "tag_CloudAccounts": "Same Format as above"
}

到目前为止,我已经尝试使用reduce来实现这个目标:

代码语言:javascript
复制
. as $all |  reduce .tags as $tag  ({}; . + {"tag_" + $tag.name: (($all.paths) | select(.[][].tags | contains([$tag.name]))) })

但甚至不能使查询有效。在这一点上真的迷路了。

任何帮助/指针都非常感谢

EN

回答 4

Stack Overflow用户

发布于 2022-11-13 20:39:11

您可以基于.tags数组构建一个键值对数组,最终可以使用from_entries将其转换为对象。使用del删除不想包含的内容。

代码语言:javascript
复制
[.tags[] as $tag | {key: "tag_\($tag.name | gsub(" "; ""))", value: del(
  
  .openapi,
  (.tags[] | select(. != $tag)),
  (.paths[] | select(IN(.[].tags[]; $tag.name) | not))
  
)}] | from_entries
代码语言:javascript
复制
{
  "tag_RotorParts": {
    "info": {
      "description": "Prisma Cloud REST APIs for external use.",
      "version": "v1",
      "title": "Prisma Cloud REST API Doc",
      "contact": {},
      "license": {
        "name": "Public"
      }
    },
    "tags": [
      {
        "name": "Rotor Parts",
        "description": "Rotor Parts API"
      }
    ],
    "paths": {
      "/access_keys": {
        "get": {
          "tags": [
            "Rotor Parts"
          ],
          "summary": "List Rotor Parts",
          "description": "Returns all rotor parts if you have an Admin role. Returns just your rotor parts if you don't have this role.",
          "operationId": "get-my-rotor-parts",
          "responses": {
            "200": {
              "description": "successful operation",
              "content": {
                "application/json": {
                  "schema": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RotorPartsResponseModel"
                    }
                  }
                }
              }
            },
            "400": {
              "description": "user_inactive_or_not_exist"
            },
            "403": {
              "description": "unauthorized_to_use_rotor_parts"
            },
            "500": {
              "description": "failed_fetch_user_profile"
            }
          }
        },
        "post": {
          "tags": [
            "Rotor Parts"
          ],
          "summary": "Add Rotor Parts",
          "description": "Adds a new rotor part for the current user. If you have API access, you can create up to two rotor parts.",
          "operationId": "add-rotor-parts",
          "requestBody": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRotorPartRequestModel"
                }
              }
            },
            "description": "Model user rotor part model",
            "required": true
          },
          "responses": {
            "200": {
              "description": "successful operation",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/CreateUserAccessKeyResponseModel"
                  }
                }
              }
            },
            "400": {
              "description": "invalid_expiry_access_key / already_have_two_access_keys / invalid_access_key_name_length / invalid_access_key_name"
            },
            "403": {
              "description": "unauthorized_to_use_access_keys"
            },
            "409": {
              "description": "duplicate_access_key_name"
            }
          }
        }
      }
    }
  },
  "tag_CloudAccounts": {
    "info": {
      "description": "Prisma Cloud REST APIs for external use.",
      "version": "v1",
      "title": "Prisma Cloud REST API Doc",
      "contact": {},
      "license": {
        "name": "Public"
      }
    },
    "tags": [
      {
        "name": "Cloud Accounts",
        "description": "Plant Locations APIs"
      }
    ],
    "paths": {
      "/account/{accountId}/config/status": {
        "get": {
          "tags": [
            "Cloud Accounts"
          ],
          "summary": "List Account Status Details",
          "description": "Returns a list of Cloud services whose status indicates a warning or error for the given cloud account ID. Includes status details for each listed service.",
          "operationId": "list-cloud-account-status-details",
          "parameters": [
            {
              "name": "accountId",
              "in": "path",
              "description": "Cloud account ID",
              "required": true,
              "schema": {
                "type": "string"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "successful operation",
              "content": {
                "application/json; charset=UTF-8": {
                  "schema": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/CloudAccountConfigStatusView"
                    }
                  }
                }
              }
            },
            "400": {
              "description": "bad_request"
            },
            "500": {
              "description": "internal_error"
            }
          }
        }
      }
    }
  }
}

演示

票数 0
EN

Stack Overflow用户

发布于 2022-11-13 20:55:29

下面是一个看起来可行的解决方案:

代码语言:javascript
复制
. as {$info, $paths}
| .tags
| map(
    . as $tag
    | (.name |= "tag_" + gsub(" "; ""))
    | .value = {
        $info,
        tags: [ $tag ],
        paths: $paths | map_values(
            with_entries(select(IN(.value.tags[]; $tag.name)))
            | select(length > 0)
        )
    }
)
| from_entries
票数 0
EN

Stack Overflow用户

发布于 2022-11-13 21:49:48

您可以将其重新表示为按组标记,然后进行转换:

代码语言:javascript
复制
def group(k):
  group_by(k) | map({key:first|k, value:.}) | from_entries;

. as {$info}
| INDEX(.tags[];.name) as $tags # lookup table for tags by name
| .paths
| to_entries
| group(.value[].tags[]) # group paths by their tags
| with_entries(
    [$tags[.key]] as $tags
    | .key |= "tag_" + gsub(" "; "")  # fix property names
    | .value |= { $info, $tags, paths: from_entries } # transform to result
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74424368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档