访问对象 Scala 中的属性

Accessing attributes in objects Scala

我需要从我的 json 中抓取的对象类型的示例可以在以下示例 (src) 中找到:

{
  "test": {
    "attra": "2017-10-12T11:17:52.971Z",
    "attrb": "2017-10-12T11:20:58.374Z"
  },
  "dummyCheck": false,
  "type": "object",
  "ruleOne": {
    "default": 2557
  },
  "ruleTwo": {
    "default": 2557
  }
}

在上面的示例中,我想访问 "ruleOne" 下的默认值。 我试过弄乱下面的几个不同的东西,但我似乎在挣扎。我可以获取 "dummyCheck" 之类的值。进入我需要去的地方的最佳方式是什么? 我如何尝试获取以下值的示例:

import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.DefaultFormats

implicit val formats = DefaultFormats
val test = parse(src)
println((test \ "ruleOne.default").extract[Integer])

编辑: 进一步扩展以上内容:

  def extractData(data: java.io.File) = {
    val json = parse(data)
    val result = (json \ "ruleOne" \ "default").extract[Int]
    result
  }

如果我将上面的扩展成一个通过传入调用的函数:

extractData(src)

那只会给我 RuleOne.default.. 有没有一种方法可以扩展它,以便我可以动态地将多个字符串参数传递给它来解析(如 splat)

  def extractData(data: java.io.File, path: String*) = {
    val json = parse(data)
    val result = (json \ path: _*).extract[Int]
    result
  }

所以消费它就像

extractData(src, "ruleOne", "default")

这适用于 "json4s-jackson" % "3.6.0-M2",但它应该以与 native 后端完全相同的方式工作。

val src = """
  |{
  |  "test": {
  |    "attra": "2017-10-12T11:17:52.971Z",
  |    "attrb": "2017-10-12T11:20:58.374Z"
  |  },
  |  "dummyCheck": false,
  |  "type": "object",
  |  "ruleOne": {
  |    "default": 2557
  |  },
  |  "ruleTwo": {
  |    "default": 2557
  |  }
  |}""".stripMargin

import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.DefaultFormats

implicit val formats = DefaultFormats
val test = parse(src)
println((test \ "ruleOne" \ "default").extract[Int])

输出:

2557

要使其与 native 一起使用,只需替换

import org.json4s.jackson.JsonMethods._

来自

import org.json4s.native.JsonMethods._

并确保您具有正确的依赖项。


编辑

这里有一个vararg将字符串参数转换为路径的方法:

def extract(json: JValue, path: String*): Int = {
  path.foldLeft(json)(_ \ _).extract[Int]
}

有了这个,您现在可以:

println(extract(test, "ruleOne", "default"))
println(extract(test, "ruleTwo", "default"))

请注意,它接受 JValue,而不是 File,因为带有 File 的版本测试起来会不必要地痛苦,而 JValue 版本可以使用已解析的字符串常量进行测试。