繁体   English   中英

使用Scala的json4s在嵌套的json中提取字段

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM