我正在尝试 json4s 库(基于 lift-json)。我想做的一件事是将 JSON 字符串解析为 AST,然后对其进行操作。
例如,我想更新插入一个字段(如果该字段不存在,则将该字段插入到 AST 中,如果存在,则更新其值)。
我无法在文档中找到如何执行此操作。通过尝试可用的方法,我提出了以下方法,该方法有效,但感觉很笨拙。
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
object TestJson {
implicit val formats = DefaultFormats
def main(args: Array[String]): Unit = {
val json = """{"foo":1, "bar":{"foo":2}}"""
val ast = parse(json).asInstanceOf[JObject]
println( upsertField(ast, ("foo" -> "3")) )
println( upsertField(ast, ("foobar" -> "3")) )
}
def upsertField(src:JObject, fld:JField): JValue = {
if(src \ fld._1 == JNothing){
src ~ fld
}
else{
src.replace(List(fld._1), fld._2)
}
}
}
我不喜欢它有很多原因:
- 必须显式地转换结果
parse(json)
to JObject
- 结果
upsertField
函数是一个JValue
,如果我想进一步操作该对象,我将不得不重新转换它
- The
upsertField
功能感觉很不优雅
- 它不适用于不在层次结构顶层的字段
有没有更好的方法来改造 AST?
编辑:作为解决该问题的方法,我设法将 JSON 转换为 Scala 常规类,并使用镜头操作它们(在 Scala 常规类中使用 Lenses https://stackoverflow.com/questions/17255228/using-lenses-on-scala-regular-classes/17255837#17255837)
有创建或覆盖字段的合并功能。您还可以更新不在树根级别的字段。
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
object mergeJson extends App {
val json =
"""
|{
| "foo":1,
| "bar": {
| "foo": 2
| }
|}
|""".stripMargin
val ast = parse(json)
val updated = ast merge (("foo", 3) ~ ("bar", ("fnord", 5)))
println(pretty(updated))
// {
// "foo" : 3,
// "bar" : {
// "foo" : 2,
// "fnord" : 5
// }
// }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)