scala - 如何在Scala中操作JSON AST

标签 scala lift-json json4s

我正在尝试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)的结果显式转换为JObject
  • upsertField函数的结果是一个JValue,如果我想进一步操作该对象,我将不得不重铸
  • upsertField函数感觉很不舒服
  • 对于不在层次结构
  • 顶层的字段不起作用

    有没有更好的方法来转换AST?

    编辑:作为解决该问题的方法,我设法将JSON转换为Scala常规类,并使用lens(Using Lenses on Scala Regular Classes)对其进行操作。

    最佳答案

    有合并功能可以创建或覆盖字段。您还可以更新不在树的根级别上的字段。

    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
      //    }
      //  }
    
    }
    

    关于scala - 如何在Scala中操作JSON AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17254573/

    相关文章:

    scala - 如何使用 Scalaz 或 Cats 重构抛出异常的函数

    java - 从 Scala 函数到 Java 函数的隐式转换

    json - 如何使用 json4s 将 JString 转换为 Int

    json - 使用 json4s 解析 JSON 中的空值

    scala - 从 Antlr 生成 Scala 代码

    scala - 在 Play Framework 中发送文件后进行清理

    java - 如何为 Java 8 LocalDateTime 编写自定义序列化器

    scala - 如何将 JNothing 序列化为 null

    scala - 是否可以在 Scala 中序列化非案例类?

    scala - Json4s 忽略 @JsonProperty jackson 注释