首页 > 解决方案 > 如何根据 Java 中的给定深度深度选择节点?

问题描述

我有如下的json表示:

{
  "total": "555",
  "offset": "555",
  "hasMore": "false",
  "results": [
    {
      "associations": {
        "workflowIds": [],
        "companyIds": [],
        "ownerIds": [],
        "child": {
         "name" : "association1",
          "key" : "a1"
        }, 
        "quoteIds": [],
        "contentIds": [],
        "dealIds": [],
        "contactIds": [
          4646915
        ],
        "ticketIds": []
      },
      "scheduledTasks": [
        {
          "taskType": "REMINDER",
          "portalId": 214129,
          "engagementType": "TASK",
          "engagementId": 6604524566,     
          "timestamp": 1586815200000
        }
      ]
    },
    {
      "associations": {
        "workflowIds": [],
        "companyIds": [],
        "ownerIds": [],
        "quoteIds": [],
        "contentIds": [],
        "child": {
         "name" : "association2",
          "key" : "a2"
        }, 
        "dealIds": [],
        "contactIds": [
          4646915
        ],
        "ticketIds": []
      }
    },
    {
      "associations": {
        "workflowIds": [],
        "companyIds": [],
        "ownerIds": [],
        "quoteIds": [],
        "contentIds": [],
        "dealIds": [],
        "child": {
         "name" : "association3",
          "key" : "a3"
        }, 
        "contactIds": [
          3995065
        ],
        "ticketIds": []
      }
    },
    {
      "associations": {
        "workflowIds": [],
        "companyIds": [],
        "ownerIds": [],
        "quoteIds": [],
        "contentIds": [],
        "dealIds": [],
        "contactIds": [
          4648365
        ],
        "ticketIds": []
      }
    }
]
}

我想通过传递节点选择器字符串来获取给定节点的过滤信息(类似于 sql),为了实现这一点,我正在执行如下操作:

ObjectMapper objectMapper = new ObjectMapper();
        JsonNode root = objectMapper.readTree(new File("/Users/pra/automation/foo.json"));
       String result = root.at("/results/0/associations/0/child").toString();
       Assert.assertNotNull(result);

并且此代码也可以正常工作,它会从数组中过滤出第一个节点,因为传递了 0 级索引,但是我需要所有匹配元素的输出,以实现我传递了 * 而不是 0 但它不起作用。

意味着我正在尝试类似下面的东西(这是失败的):

String result = root.at("/results/*/associations/*/child").toString();

所需的输出:

[
{
   "name" : "association1",
   "key" : "a1"
},
{
   "name" : "association2",
   "key" : "a2"
},
{
   "name" : "association3",
   "key" : "a3"
}
]

我愿意接受其他基于 Java 的替代方案来实现这一目标。谢谢。

标签: javajsonspringjacksonmodelmapper

解决方案


我发现 Andreas 的建议非常有效且易于使用,我能够通过使用 JSONPath来实现所需的输出 。

使用代码如下:

ObjectMapper objectMapper = new ObjectMapper();
String root = objectMapper.readTree(new File("/Users/pramo/automation/foo.json")).toString();
List<Object> associations = JsonPath.read(root, "$.results[*].associations.child");

推荐阅读