Scala - 如何使用 json-path 拆分列表 Json 节点的所有列表
Scala - How to Split all List of List Json Nodes using json-path
我有一个 Json,我想从中选择列表 Json 的列表,其中列表中的实例可以是多个。如果给出 List/Array 的索引号,我们可以轻松地使用 json-path 选择。但是在一个大文件中,我们不知道总共有多少个实例,我们不必丢失任何数据。因此必须以动态方式检查实例数,并为所有内部列表节点选择单独的 json。此外还必须为所有数据创建 relation_path。
任何人都可以建议如何检查 json 节点是否为 Array/List(例如:2 个驱动器)以及有多少嵌套列表对象可用,例如第一个驱动器中的 2 个分区和第二个驱动器中的 1 个分区驾驶。这些数字未固定在 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)
这是我能想到的最简单的解决方案:
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。它使用驱动器的索引值来创建 relation_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")))
})
我有一个 Json,我想从中选择列表 Json 的列表,其中列表中的实例可以是多个。如果给出 List/Array 的索引号,我们可以轻松地使用 json-path 选择。但是在一个大文件中,我们不知道总共有多少个实例,我们不必丢失任何数据。因此必须以动态方式检查实例数,并为所有内部列表节点选择单独的 json。此外还必须为所有数据创建 relation_path。
任何人都可以建议如何检查 json 节点是否为 Array/List(例如:2 个驱动器)以及有多少嵌套列表对象可用,例如第一个驱动器中的 2 个分区和第二个驱动器中的 1 个分区驾驶。这些数字未固定在 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)
这是我能想到的最简单的解决方案:
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。它使用驱动器的索引值来创建 relation_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")))
})