Scala - Как разделить весь список из списка Json Узлы, используя json -path - PullRequest
0 голосов
/ 11 июля 2020

У меня есть Json, из которого я хочу выбрать List of List Json, где экземпляров может быть несколько внутри List. Используя json -path, мы можем легко выбрать, если даем индексный номер List / Array. Но в большом файле мы не знаем всего, сколько экземпляров будет там, и мы не должны терять никаких данных. Таким образом, количество экземпляров должно быть проверено динамически c способом и выбрать json отдельно для всех внутри узла списка. Кроме того, необходимо создать Relations_path также для всех данных.

Кто-нибудь может предложить, как проверить, является ли узел json массивом / списком (например, 2 диск) и сколько вложенных объектов списка доступно, например, 2 раздела на 1-м диске и 1 раздел на 2-м диске. Эти числа не фиксированы для предоставления в коде пути json.

Входной список списка Json:

{"Start":{"HInfo":{"InfoId":"650FEC74","Revision":"5.2.0.51","Drive":[{"InfoId":"650FEC74","Index":0,"Name":"Drive0","Partition":[{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":0},{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":1}]},{"InfoId":"650FEC74","Index":1,"Name":"Drive1","Partition":{"InfoId":"650FEC74","DriveID":"3F275869","Index":0}}]}}}

Выходной список Json:

[{"Partition":[{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":0},{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":1}],"relation_tree":"Start/HInfo/Drive/Drive-1/Partition"},{"Partition":{"InfoId":"650FEC74","DriveID":"3F275869","Index":0},"relation_tree":"Start/HInfo/Drive/Drive-2/Partition"}]

То, что я пытаюсь использовать json -path, но это не подходит, поскольку я здесь я указываю номер индекса вручную, что невозможно во всех случаях, поскольку номер индекса может быть от 0 до любого.

val jsonString = """{"Start":{"HInfo":{"InfoId":"650FEC74","Revision":"5.2.0.51","Drive":[{"InfoId":"650FEC74","Index":0,"Name":"Drive0","Partition":[{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":0},{"InfoId":"650FEC74","DriveID":"F91B1F36","Index":1}]},{"InfoId":"650FEC74","Index":1,"Name":"Drive1","Partition":{"InfoId":"650FEC74","DriveID":"3F275869","Index":0}}]}}}"""
  val jsonStr: JsValue = Json.parse(jsonString)
    var pruneJson1 = (__ \ "Partition").json.copyFrom((__ \ "Start" \ "HInfo" \ "Drive" \ (0) \ "Partition").json.pick)
    val finalPartitionPrune1 = Option(jsonStr.transform(pruneJson1)).get.get.as[JsObject] + ("relation_tree" -> Json.toJson("Start"+"/"+"HInfo"+"/"+"Drive"+"/"+"Drive-1"+"/"+"Partition"))

    println(finalPartitionPrune1)

  var pruneJson2 = (__ \ "Partition").json.copyFrom((__ \ "Start" \ "HInfo" \ "Drive" \ (1) \ "Partition").json.pick)
  val finalPartitionPrune2 = Option(jsonStr.transform(pruneJson2)).get.get.as[JsObject] + ("relation_tree" -> Json.toJson("Start"+"/"+"HInfo"+"/"+"Drive"+"/"+"Drive-2"+"/"+"Partition"))

   println(finalPartitionPrune2)

1 Ответ

0 голосов
/ 17 июля 2020

Это самое простое решение, которое я мог придумать:

val finalJson = Json.toJson(
  (jsonStr \ "Start" \ "HInfo" \ "Drive")
    .as[Seq[JsValue]]
    .map(jsValue => JsObject(Seq(
      "Partition" -> (jsValue \ "Partition").get,
      "relation_tree" -> JsString(s"Start/HInfo/Drive/Drive-${(jsValue \ "Index").get}/Partition")))))

В основном он считывает все диски как последовательность JsValues, а затем сопоставляет их с JsObjects в необходимом формате. Он использует значение индекса диска для создания значения Relations_tree, поэтому он завершится ошибкой, если это значение отсутствует. В качестве альтернативы вы можете использовать метод zipWithIndex для добавления ваших собственных индексов в последовательность. В качестве последнего шага он преобразует последовательность обратно в JsValue

Вот версия zipWithIndex:

val finalJson =   Json.toJson(
  (jsonStr \ "Start" \ "HInfo" \ "Drive")
    .as[Seq[JsValue]]
    .zipWithIndex
    .map{ case (jsValue, index) => JsObject(Seq(
      "Partition" -> (jsValue \ "Partition").get,
      "relation_tree" -> JsString(s"Start/HInfo/Drive/Drive-$index/Partition")))
    })
...