如何根据 Java 中的给定深度加深 select 节点?

How to deep select Nodes based on given depth in 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 的替代方案来实现这一目标。谢谢。

如果您可以切换到 Gson 库,您可以使用 im.wilk.vor:VoritemgitHub 或 Maven 存储库。

VorItem vorItemFactory = VorItemFactoryBuilder.standard.build();
JsonElement je = JsonParser.parse(...)

VorItem vi = vorItemFactory.from(je);
VorItem result = vorItemFactory.empty();

for (int idx = 0; idx < vi.get("result").list().size(); idx++) {
    result.get(idx).set("name", vi.get("result").get(idx).get("associations/child/name");
    result.get(idx).set("key", vi.get("result").get(idx).get("associations/child/key");

}

return result.asJsonElement().toString();

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

使用代码如下:

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");