我读过其他Scala解析问题,但它们似乎都假设了一个非常基本的文档,它不是深度嵌套的,也不是混合类型的。或者,他们假设您了解文档的所有成员,或者说有些成员永远不会失踪。
我目前正在使用Jackson的流式API,但是所需的代码很难理解和维护。相反,如果可能的话,我想使用杰克森返回一个表示解析的JSON的对象。
基本上:我想复制我在动态语言中非常熟悉的JSON解析功能。我意识到这可能是非常错误的,所以我来这里接受教育。
比如说我们有条推特:
{
"id": 100,
"text": "Hello, world."
"user": {
"name": "Brett",
"id": 200
},
"geo": {
"lat": 10.5,
"lng": 20.7
}
}现在,Jerkson案例类示例非常有意义,当您只想解析出,比如说ID:
val tweet = """{...}"""
case class Tweet(id: Long)
val parsed = parse[Tweet](tweet)但我该如何处理上面的Tweet呢?
有些问题是:
null或缺失,例如上面的"geo“可能是null,或者有一天它们会删除一个字段,我不希望我的解析代码失败。发布于 2012-07-19 22:45:51
抬起是我遇到的读和写JSON的最好方法。在这里,Docs很好地解释了它的用法:
https://github.com/lift/framework/tree/master/core/json-scalaz
发布于 2012-07-19 20:20:27
当然,在我发完这篇文章后,我会在其他地方找到一些帮助。:)
我认为“更丰富的JSON示例”是朝着正确方向迈出的一步:http://bcomposes.wordpress.com/2012/05/12/processing-json-in-scala-with-jerkson/
发布于 2012-07-21 19:54:24
另一种使用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上缺少geo数据时,解析工作得很好,期望为None。
还是希望得到案例类作为结果?
有关案例类示例,请参见:
封装code.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
}
}
}https://stackoverflow.com/questions/11568408
复制相似问题