0

I am currently trying to filter out some path values from a swagger json document, by using jq.

The JSON looks something like this:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.2",
    "title": "Some API"
  },
  "host": "example.com",
  "basePath": "/",
  "paths": {
    "/api/companies": {
      "get": {
        "tags": [ "company-tag" ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/CompanyDTO" }
          }
        }
      }
    },
    "/api/account": {
      "get": {
        "tags": [ "account-tag" ],
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      },
      "post": {
        "tags": [ "account-tag" ],
        "operationId": "createAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      }
    }
  }
}

I would like to filter the paths values, so that I can get only the paths that contain a specific tag inside the tags array.

For example: if I want to get the paths for the account-tag the JSON should look like this after filtering:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.2",
    "title": "Some API"
  },
  "host": "example.com",
  "basePath": "/",
  "paths": {
    "/api/account": {
      "get": {
        "tags": [ "account-tag" ],
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      },
      "post": {
        "tags": [ "account-tag" ],
        "operationId": "createAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      }
    }
  }
}

EDIT

Ikegami's second suggestion worked as expected. Here is my final solution

1 Answer 1

1

If we assume all methods (get, post, etc) of a given path share the same tags, we can simply use the following:

.paths |= with_entries( select( .value[].tags | index("account-tag") ) )

Demo on jqplay


If that assumption doesn't hold, we'll need to filter at two levels.

.paths |= with_entries(
   .value |= with_entries(
      select( .value.tags | index("account-tag") )
   ) |
   select( .value | length > 0 )
)

Demo on jqplay

or

.paths |= with_entries(
   .value = (
      .value |
      with_entries(
         select( .value.tags | index("account-tag") )
      ) |
      select( length > 0 )
   )
)

Demo on jqplay

(I hate that I have to use .value = ( .value | ... ) instead of .value |= ( ... ) here.)

Sign up to request clarification or add additional context in comments.

4 Comments

The first assumption cannot be made. However your second suggestion seems to work as expected. I would like to mark your Answer as correct :) can you add this little demo to your answer? jqplay.org/s/4VmYatAx-- It contains the fully working query with the example from the question
Also checked with the bigger json that I have lying around locally and it seems to work as expected. Thank you a lot :)
I purposefully didn't use the JSON from the OP because it doesn't show that the code works. It has no URL for which the get and the post have different tags.
Yeah, the json sort of evolved during the discussion in the already deleted answer, so while you were tinkering the question was edited. Sorry about that. I also realized that it is good enough to add the demo to the Question, so no worries about that. Again thanks it saved me a lot of time :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.