scala - 处理嵌套的json和丢失的文件

时间:2018-03-29 06:43:47

标签: json scala

我希望处理json文件,如下所示

{
    "fixed": "abc",
    "issues": [{
        "issue": "issue0",
        "fields": {
            "value": "value1"
        }
    }, {
        "issue": "issue1",
        "fields": {
            "value": "value2"
        }
    }]
}

我希望爆炸json。我可以做很多事情。 我正在寻找方法来处理丢失的json字段。

例如,我需要查询可能存在于某些json文件中的字段“nonxistingcolumn”,而不是在另一个json文件中。

输出应该是表格式的,如下所示。

fixed |  issue |  value | nonexitingcolumn
abc   | issue0 | value1 | null
abc   | issue1 | value2 | null

更新: nonxistingcolumn是嵌套json的一部分,例如ex:“issues.fields.name”。

1 个答案:

答案 0 :(得分:0)

我的解决方案包括几个步骤:

  1. 将json解析为某个模型对象。
  2. 建立表格
  3. (可选)表的控制台输出
  4. 第一步可以由play-json库完成:

    libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.7"
    

    该库允许自动生成格式化程序,这有助于将json解析为相应的Scala类。也许其他json库也可以实现相同的效果。

    第二步和第三步是技术性的。关键是我们建模"字段"对象作为Map [String,String]。

    val json: JsValue = Json.parse(
        """
      {
        "fixed": "abc",
        "issues": [{
        "issue": "issue0",
        "fields": {
          "value": "value1"
        }
      }, {
        "issue": "issue1",
        "fields": {
          "value": "value2",
          "nonexistingcolumn": "blabla"
        }
      }]
      }""")
    
      case class Issue(issue: String, fields: Map[String, String])
      case class Model(fixed: String, issues: List[Issue])
    
      implicit val issueFormat = Json.format[Issue]
      implicit val modelFormat = Json.format[Model]
    
      val model = json.as[Model]
    
      val fieldNames = (for {
        issue <- model.issues
        field <- issue.fields
      } yield field._1) distinct
    
      val table = model.issues map { issue =>
        model.fixed :: issue.issue :: (fieldNames map { fieldName =>
          issue.fields.getOrElse(fieldName, "null")
        })
      }
    
      val headers = (List("fixed", "issue") ++ fieldNames)
      val tableWithHeaders =  headers :: table
    
      tableWithHeaders foreach { row =>
        println(row map (" %-20s ".format(_)) mkString("|"))
      }