[英]Extract fields in nested json using Scala's json4s
给定一个解析的(通过json4s)json字符串,例如以下org.json4s.JValue
:
val data: JValue = parse("""{
"important_field" : "info",
"some_junk" : 12345,
"interesting_stuff" : {
"pi" : 3.14,
"e" : 2.72
}
}""")
我可以有选择地提取我需要的信息:
case class Data(important_field: String)
val extracted: Data = data.extract[Data]
extracted: Data = Data(info)
。 此外,我可以从另一个案例类的嵌套json对象中提取信息:
case class Stuff(pi: Double)
case class Data(important_field: String, interesting_stuff: Stuff)
val extracted: Data = data.extract[Data]
这让我解extracted: Data = Data(info,Stuff(3.14))
。 但是现在,如果我想访问嵌套对象中的字段,我需要使用Stuff
,我的内部案例类:
val pi: Double = extracted.interesting_stuff.pi
我宁愿放弃嵌套,所以Data
是平的,即我想访问(原始)嵌套字段,如下所示:
val pi: Double = extracted.pi
在这个简单的情况下,使用嵌套类并不是那么痛苦,但是当存在多个嵌套级别时,必须在我的对象中维护嵌套是令人沮丧的。 有没有一种典型的方法来处理这个? 一些花哨的Scala技巧?
在将json内容映射到您自己的case类之前,可以转换嵌套的json结构:
object NestedJsonSpec {
case class Data(important_field: String, pi: Double)
implicit val formats = DefaultFormats // Brings in default date formats etc.
def extract(source: JsonInput) : Data = {
parse(source).transformField({
case JField("interesting_stuff", jv) => ("pi", jv \ "pi")
}).extract[Data]
}
}
因此,不必定义嵌套的案例类Stuff
。
代码中使用的依赖项是:
scalaVersion := "2.11.8"
libraryDependencies ++= {
Seq(
"org.json4s" %% "json4s-ext" % "3.5.0",
"org.json4s" %% "json4s-native" % "3.5.0",
"org.scalatest" %% "scalatest" % "2.2.6" % Test
)
}
这是与单元测试相关的github项目。
您可以在外部案例类中为嵌套字段定义一个getter
case class Data(important_field: String, interesting_stuff: Stuff) {
def pi: Double = interesting_stuff.pi
}
// now you'll be able to write
val pi: Double = extracted.pi
缺点是您必须手动为您想要轻松访问的每个嵌套字段执行此操作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.