为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 JSON 中获取子元素的父元素名称?

如何在 JSON 中获取子元素的父元素名称?

慕后森 2022-05-25 15:42:13
我有一些动态 JSON,在处理之前我不知道完整的结构。但是,我知道 JSON 可能包含某些感兴趣的嵌套元素。e. 对于这个示例有效载荷{  "id": "3334343",  "contractor": {    "ppsNo": "123334"  },  "fullTimeStaff":{    "ppsNo": "343434"  }}我想找到包含名为ppsNo的元素的所有外部元素的名称。我曾尝试使用root.findParents("ppsNo")但这给了我 ppsNo 元素,而不是我感兴趣的承包商和fullTimeStaff的外部(父)元素。    ObjectMapper objectMapper = new ObjectMapper();    String payload = "{\n" +            "  \"id\": \"3334343\",\n" +            "  \"contractor\": {\n" +            "    \"ppsNo\": \"123334\"\n" +            "  },\n" +            "  \"fullTimeStaff\":{\n" +            "    \"ppsNo\": \"123334\"\n" +            "  }\n" +            "}";    JsonNode root = objectMapper.readTree(payload);    List<JsonNode> nodes = root.findParents("ppsNo");返回的 JsonNodes 是{"ppsNo":"123334"}元素而不是外部包含节点(“contractor”和“fullTimeStaff”)。有没有办法做到这一点?我曾研究过使用 JSON 路径,但我看不到一种明显的方法来使用它来获取真正的父(包含/外部)元素。我在这个例子中使用杰克逊,但我对替代品持开放态度
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

JsonPath 库有一个选项,它返回整个匹配的路径而不是值。因此,您可以执行以下操作:


Configuration conf = Configuration.builder().options(Option.AS_PATH_LIST).build();

List<String> pathList = JsonPath.using(conf).parse(payload).read("$..ppsNo");


/* Returns :

 * [

 *   "$['contractor']['ppsNo']",

 *   "$['fullTimeStaff']['ppsNo']"

 * ]

 */

您只需将结果解析为正确的类型,然后删除最后一个元素即可获得直接父级。


Pattern pattern = Pattern.compile("(?<!\\$\\[)(\\w+)(?!\\])");

pathList = pathList.stream().map(path -> {

    Matcher m = pattern.matcher(path.toString());

    return m.find() ? m.group(0) : null;

}).collect(Collectors.toList());

System.out.println(pathList); // [contractor, fullTimeStaff]

这是官方Jayway JsonPath Maven 存储库的链接。


查看完整回答
反对 回复 2022-05-25
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

我没有花很多时间来编写代码。

您正在寻找的表达式Regex\{\n    "ppsNo": "\w+"\n  }(您使用链接https://regex101.com对其进行测试)。你应该做的是当你遇到这个表达式时开始倒退并阅读“”中的第一个单词。我希望它对你有帮助


查看完整回答
反对 回复 2022-05-25
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

我们可以在JsonNode.fields方法的帮助下使用递归来搜索目标父节点,如下例所示。

public class GetParentByChildName {

    public static void main(String[] args) throws IOException {


        ObjectMapper objectMapper = new ObjectMapper();

        String payload = "{                                      \n"

                + "  \"id\": \"3334343\",                        \n"

                + "  \"contractor\": {                           \n"

                + "    \"ppsNo\": \"123334\"                     \n"

                + "  },                                          \n"

                + " \"arr\": [                                   \n"

                + "    {                                         \n"

                + "      \"contractor2\": {                      \n"

                + "        \"ppsNo\": \"123334\"                 \n"

                + "      }                                       \n"

                + "    },                                        \n"

                + "    [                                         \n"

                + "      {                                       \n"

                + "        \"contractor3\": {                    \n"

                + "          \"ppsNo\": \"123334\"               \n"

                + "        }                                     \n"

                + "      }                                       \n"

                + "    ]                                         \n"

                + "  ],                                          \n"

                + "  \"fullTimeStaff\":{                         \n"

                + "    \"ppsNo\": \"123334\"                     \n"

                + "  }                                           \n"

                + "}                                               ";


        JsonNode root = objectMapper.readTree(payload);

        List<String> fieldNames = new ArrayList<String>();

        getParentName(root, "ppsNo", fieldNames);

        System.out.println(fieldNames);

    }


    private static void getParentName(JsonNode node, String targetChildName, List<String> fieldNames) {

        if (node.getNodeType() == JsonNodeType.ARRAY) {

            node.elements().forEachRemaining(x -> getParentName(x, targetChildName, fieldNames));

            return;

        }

        if (node.getNodeType() != JsonNodeType.OBJECT) {

            return;

        }

        node.fields().forEachRemaining(x -> {

            Iterator<String> iter = x.getValue().fieldNames();

            while (iter.hasNext()) {

                String fieldName = iter.next();

                if (fieldName.equals(targetChildName)) {

                    fieldNames.add(x.getKey());

                }

            }

            getParentName(x.getValue(), targetChildName, fieldNames);

        });

    }

}


查看完整回答
反对 回复 2022-05-25
  • 3 回答
  • 0 关注
  • 243 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信