获取嵌套元素的 jsonpath 而无需为父级提供放心

Get jsonpath for nested elements without providng the parent with rest assured

我需要从这个JSON中获取label所有值作为数组,放心

这是例子JSON

{
  "additionalProp1": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  },
  "additionalProp2": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  },
  "additionalProp3": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  }
}

使用 jsonpath 提取器是 *.label

但我需要放心地提取路径

.extract().path("*.label");

但是它不起作用,我如何编写JSON获取所需数组的路径?

如果我对问题的理解正确,你想提取与键相关的所有值。如果我错了请纠正我。
我不知道如何使用 jsonPath,但我可以为您提供一些代码。
也许您对通过代码来做不感兴趣。但是如果您想以编程方式进行或阅读该问题的人对此感兴趣,您可以使用递归来获得结果。
我用这种方法做其他事情,但我根据您的需要进行了调整。如果你愿意,你可以看到original code

这里有一个例子:

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        String payload = "<YOUR_JSON_PAYLOAD>";

        // Create A json Object
        JSONObject jsonObject = new JSONObject(payload);

        // Initialize a list where store objects
        List<Object> values = new ArrayList<>();

        // Recursively find values by specifying key
        getValuesByKey(values, jsonObject, "label");

        System.out.println(values.toString());
    }


    // recursive
    private static void getValuesByKey(final List<Object> collection, JSONObject jsonObject, String targetKey) {
        for (String key : jsonObject.keySet()) {
            // Our targets
            if (key.equals(targetKey) && (jsonObject.get(key) instanceof String
                    || jsonObject.get(key) instanceof JSONArray
                    || jsonObject.get(key) instanceof Number
                    || null == jsonObject.get(key))) {

                collection.add(jsonObject.get(key));
            } else if (jsonObject.get(key) instanceof JSONObject) {
                // Going through simple JSON Object
                JSONObject modObj = (JSONObject) jsonObject.get(key);

                if (null != modObj) {
                    getValuesByKey(collection, modObj, targetKey);
                }
            } else if (jsonObject.get(key) instanceof JSONArray) {
                // Going through simple JSONArrays
                JSONArray modArray = (JSONArray) jsonObject.get(key);
                
                for (int i = 0; i < modArray.length(); i++) {
                    JSONObject nextObj = modArray.optJSONObject(i);
                    if (null != nextObj) getValuesByKey(collection, nextObj, targetKey);
                }
            }
        }
    }
}

运行 使用您的 json 有效负载的代码我得到以下输出:
[string, string, string, string, string, string]


我稍微修改了payload,验证提取值是否正确,如下:

{
  "additionalProp1": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string0",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string00",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  },
  "additionalProp2": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string1",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string11",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  },
  "additionalProp3": {
    "type": "FADE_IN",
    "applyType": "IN",
    "label": "string2",
    "properties": [
      {
        "name": "string",
        "type": "NUMERIC",
        "elementType": "TEXT",
        "label": "string22",
        "defaultValue": {},
        "displayOrder": 0,
        "required": true,
        "visible": true,
        "dataset": {
          "type": "string",
          "subtype": "string",
          "filter": "string"
        }
      }
    ]
  }
}

产生这个:
[string0, string00, string2, string22, string1, string11]


您需要 org.json library 才能使代码正常工作:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20201115</version>
</dependency>

这个查询应该适合你:

.extract().path("collect{it.value.label}");

注意: 如果您将 'label' 字段作为可选字段(可能会在响应中遗漏),则输出数组中会有空元素。

响应:

{
    "additionalProp1": {
      "type": "FADE_IN",
      "applyType": "IN",
      "label": "label1"
    },
    "additionalProp2": {
      "type": "FADE_OUT",
      "applyType": "IN",
      "label": "label2"
    },
    "additionalProp5": {
      "type": "FADE_IN",
      "applyType": "IN"
    },
    "additionalProp3": {
      "type": "FADE_IN",
      "applyType": "IN",
      "label": "label3"
    },
    "additionalProp4": {
      "type": "FADE_IN",
      "applyType": "IN"
    }
  }

查询:

ArrayList<String> body = given().when().get("http://localhost:3000/response").then().extract().path("collect{it.value.label}");

输出:

[label1, label2, null, label3, null]