如何使用标准 Scala 类在 Scala 中解析 JSON?
我正在使用 Scala 2.8 中的 JSON 类构建来解析 JSON 代码。由于依赖性最小化,我不想使用 Liftweb 之一或任何其他。
我这样做的方式似乎太必要了,有更好的方法吗?
import scala.util.parsing.json._
...
val json:Option[Any] = JSON.parseFull(jsonString)
val map:Map[String,Any] = json.get.asInstanceOf[Map[String, Any]]
val languages:List[Any] = map.get("languages").get.asInstanceOf[List[Any]]
languages.foreach( langMap => {
val language:Map[String,Any] = langMap.asInstanceOf[Map[String,Any]]
val name:String = language.get("name").get.asInstanceOf[String]
val isActive:Boolean = language.get("is_active").get.asInstanceOf[Boolean]
val completeness:Double = language.get("completeness").get.asInstanceOf[Double]
}
I am using the build in JSON class in Scala 2.8 to parse JSON code. I don't want to use the Liftweb one or any other due to minimizing dependencies.
The way I am doing it seems too imperative, is there a better way to do it?
import scala.util.parsing.json._
...
val json:Option[Any] = JSON.parseFull(jsonString)
val map:Map[String,Any] = json.get.asInstanceOf[Map[String, Any]]
val languages:List[Any] = map.get("languages").get.asInstanceOf[List[Any]]
languages.foreach( langMap => {
val language:Map[String,Any] = langMap.asInstanceOf[Map[String,Any]]
val name:String = language.get("name").get.asInstanceOf[String]
val isActive:Boolean = language.get("is_active").get.asInstanceOf[Boolean]
val completeness:Double = language.get("completeness").get.asInstanceOf[Double]
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你可以这样做!非常容易解析 JSON 代码:P
You can do like this! Very easy to parse JSON code :P
这是我使用 Scala Parser Combinator Library 的方式:
This is the way I do the Scala Parser Combinator Library:
scala.util.parsing.json.JSON 已弃用。
这是 circe 的另一种方法。仅供参考的文档:https://circe.github.io/circe/cursors.html
在
build.sbt
中添加依赖,我使用的是scala 2.13.4,注意scala版本必须与库版本一致。示例1:
示例2,json有一个对象中的对象:
scala.util.parsing.json.JSON
is deprecated.Here is another approach with
circe
. FYI documentation: https://circe.github.io/circe/cursors.htmlAdd the dependency in
build.sbt
, I used scala 2.13.4, note the scala version must align with the library version.Example 1:
Example 2, json has an object within an object:
这是一个基于提取器的解决方案,它将执行类转换:
在 for 循环开始时,我人为地将结果包装在列表中,以便它在末尾生成一个列表。然后,在 for 循环的其余部分中,我使用生成器(使用
<-
)和值定义(使用=
)将利用 unapply 方法的事实。(较旧的答案已被编辑 - 如果您好奇,请检查编辑历史记录)
This is a solution based on extractors which will do the class cast:
At the start of the for loop I artificially wrap the result in a list so that it yields a list at the end. Then in the rest of the for loop I use the fact that generators (using
<-
) and value definitions (using=
) will make use of the unapply methods.(Older answer edited away - check edit history if you're curious)
这是我进行模式匹配的方式:
This is the way I do the pattern match:
我喜欢@huynhjl 的回答,它引导我走上了正确的道路。但是,它不擅长处理错误情况。如果所需的节点不存在,则会出现强制转换异常。我对此进行了稍微调整,以利用
Option
更好地处理这个问题。当然,这与其说是处理错误,不如说是避免错误。如果缺少任何 json 节点,这将产生一个空列表。您可以在执行操作之前使用
match
检查节点是否存在...I like @huynhjl's answer, it led me down the right path. However, it isn't great at handling error conditions. If the desired node does not exist, you get a cast exception. I've adapted this slightly to make use of
Option
to better handle this.Of course, this doesn't handle errors so much as avoid them. This will yield an empty list if any of the json nodes are missing. You can use a
match
to check for the presence of a node before acting...我尝试了一些方法,倾向于将模式匹配作为避免强制转换的一种方式,但在集合类型上的类型擦除方面遇到了麻烦。
主要问题似乎是解析结果的完整类型反映了 JSON 数据的结构,并且要么很麻烦,要么无法完全说明。我想这就是为什么使用 Any 来截断类型定义的原因。使用 Any 会导致需要进行强制转换。
我已经破解了下面的一些内容,该内容很简洁,但对于问题中的代码隐含的 JSON 数据非常具体。更通用的东西会更令人满意,但我不确定它是否会非常优雅。
I tried a few things, favouring pattern matching as a way of avoiding casting but ran into trouble with type erasure on the collection types.
The main problem seems to be that the complete type of the parse result mirrors the structure of the JSON data and is either cumbersome or impossible to fully state. I guess that is why Any is used to truncate the type definitions. Using Any leads to the need for casting.
I've hacked something below which is concise but is extremely specific to the JSON data implied by the code in the question. Something more general would be more satisfactory but I'm not sure if it would be very elegant.