Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Scala解析可能有一些缺失或额外字段的深度嵌套JSON文档?_Json_Scala_Jackson - Fatal编程技术网

如何使用Scala解析可能有一些缺失或额外字段的深度嵌套JSON文档?

如何使用Scala解析可能有一些缺失或额外字段的深度嵌套JSON文档?,json,scala,jackson,Json,Scala,Jackson,我读过其他Scala JSON解析问题,但它们似乎都假设一个非常基本的文档不是深度嵌套的或混合类型的。或者他们假设您知道文档的所有成员,或者某些成员永远不会丢失 我目前正在使用Jackson的流式API,但所需的代码很难理解和维护。相反,如果可能的话,我想使用返回一个表示已解析JSON的对象 基本上:我想复制我在动态语言中非常熟悉的JSON解析功能。我意识到这可能是非常错误的,所以我来这里接受教育 假设我们有一条推特: { "id": 100, "text": "Hello, world."

我读过其他Scala JSON解析问题,但它们似乎都假设一个非常基本的文档不是深度嵌套的或混合类型的。或者他们假设您知道文档的所有成员,或者某些成员永远不会丢失

我目前正在使用Jackson的流式API,但所需的代码很难理解和维护。相反,如果可能的话,我想使用返回一个表示已解析JSON的对象

基本上:我想复制我在动态语言中非常熟悉的JSON解析功能。我意识到这可能是非常错误的,所以我来这里接受教育

假设我们有一条推特:

{
 "id": 100,
 "text": "Hello, world."
 "user": {
          "name": "Brett",
          "id": 200
         },
 "geo": {
         "lat": 10.5,
         "lng": 20.7 
        }
}
现在,当您只想解析出(比如)ID时,Jerkson Case类示例非常有意义:

val tweet = """{...}"""
case class Tweet(id: Long)
val parsed = parse[Tweet](tweet)
但是我该如何处理上面的推文呢

一些陷阱:

  • 有些字段可能是
    null
    或缺失,例如上面的“geo”可能是
    null
    ,或者某一天他们可能会删除一个字段,我不希望我的解析代码失败
  • 一些字段将是额外的,或者将添加字段,我希望能够忽略它们

  • 当然,在我发布这篇文章之后,我马上在其他地方找到了一些帮助。:)


    我相信这篇文章底部的“更丰富的JSON示例”是朝着正确方向迈出的一步:

    Lift JSON scalaz是我遇到的读写JSON的最佳方式。文档在这里很好地解释了它的用法:


    使用Lift json的另一种替代方法可能是:

    package code.json
    
    import org.specs2.mutable.Specification
    import net.liftweb.json._
    
    class JsonSpecs extends Specification {
    
      implicit val format = DefaultFormats
    
      val a = parse("""{
                      | "id": 100,
                      | "text": "Hello, world."
                      | "user": {
                      |          "name": "Brett",
                      |          "id": 200
                      |         },
                      | "geo": {
                      |         "lat": 10.5,
                      |         "lng": 20.7
                      |        }
                      |}""".stripMargin)
    
      val b = parse("""{
                      | "id": 100,
                      | "text": "Hello, world."
                      | "user": {
                      |          "name": "Brett",
                      |          "id": 200
                      |         }
                      |}""".stripMargin)
    
    
      "Lift Json" should{
        "find the id" in {
          val res= (a \ "id").extract[String]
          res must_== "100"
        }
        "find the name" in{
          val res= (a \ "user" \ "name").extract[String]
          res must_== "Brett"
        }
        "find an optional geo data" in {
          val res= (a \ "geo" \ "lat").extract[Option[Double]]
          res must_== Some(10.5)
        }
        "ignore missing geo data" in {
          val res= (b \ "geo" \ "lat").extract[Option[Double]]
          res must_== None
        }
      }
    }
    
    请注意,当val b上缺少地理数据时,解析工作正常,应该是“无”

    或者您希望得到案例类作为结果

    有关案例类示例,请参见:

    包代码.json

    import org.specs2.mutable.Specification
    import net.liftweb.json._
    
    class JsonSpecs extends Specification {
    
      implicit val format = DefaultFormats
    
      case class Root(id: Int, text: Option[String], user: Option[User], geo: Option[Geo])
      case class User(name: String, id: Int)
      case class Geo(lat: Double, lng: Double)
    
    
    
    val c = parse("""{
                    | "id": 100
                    | "user": {
                    |          "name": "Brett",
                    |          "id": 200
                    |         },
                    | "geo": {
                    |         "lng": 20.7
                    |        }
                    |}""".stripMargin)
    
    
      "Lift Json" should{
        "return none for geo lat data" in {
          val res= c.extract[Root].geo.map(_.lat)
          res must_== None
        }
      }
    }
    

    我在我的网站上有一个类似的帖子。这是一篇较老的文章,但可能与您相关:查看哪里增加了对case类默认参数的支持。