Как глубоко выбрать узлы на основе заданной глубины в Java? - PullRequest
3 голосов
/ 14 апреля 2020

У меня есть 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 для достижения этой цели. Спасибо.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Я считаю предложение Андреаса очень эффективным и удобным в использовании, я смог достичь желаемого результата с помощью библиотеки 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");
0 голосов
/ 14 апреля 2020

Если вы можете переключиться на библиотеку Gson, вы можете использовать im.wilk.vor: Voritem library gitHub или в репозитории 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();
...