首页 > 解决方案 > Scala 解析非规范 JSON

问题描述

可以看到以下数据具有不同的值类型。如何获得所需的输出?

package ceshi

import scala.util.parsing.json.JSON

object ceshi1212 {
  def main(args: Array[String]): Unit = {


    class CC[T] {
      def unapply(a: Any): Option[T] = Some(a.asInstanceOf[T])
    }

    object M extends CC[Map[String, Any]]
    object L extends CC[List[Any]]
    object S extends CC[String]

    val jsonString =
      """
      {
        "languages": [
        {
            "name": "English",
            "is_active": "true",
            "completeness": "asdf"
        },
        {
            "name": "Latin",
            "is_active": "asdf",
            "completeness": "232"
        }
            ,{
                "name": "Latin",
                "is_active": "0009"
            }
            ,
            "error"
                  ]
      }
    """.stripMargin
    // 不规则json error和并列的数组类型不同 怎么解析自动跳过?
    val result = for {
      Some(M(map)) <- List(JSON.parseFull(jsonString))
      L(languages) = map("languages")
      M(language) <- languages
      S(name) = language("name")
      S(active) = language("is_active")
      S(completeness) = language.getOrElse("completeness","--")
    } yield {
      (name, active, completeness)
    }

    println(result)
    //i want result is:  List((English,true,asdf), (Latin,asdf,232),(Latain,0009,""))

  }
}

我想得到的结果是 List((English,true,asdf), (Latin,asdf,232),(Latain,0009,"")) 注意:1 字符串并不总是在数组的末尾,并且位置is indeterminate 2 我需要的三把钥匙可能不完整

标签: jsonscala

解决方案


正如评论中所说,还有其他库被推荐用于使用 json 看看这篇文章以获得一个概述:What JSON library to use in Scala?

使用特定框架(play-json)回答您的问题

我个人可以推荐使用 play json 框架。要获得您使用 play json 描述的结果,您的代码可能如下所示:

import play.api.libs.json._

val json: JsValue = Json.parse(jsonString)
val list = (json \ "languages").as[Seq[JsValue]]

val names = list.map(x => ((x\"name").validate[String] match {
  case JsSuccess(v, p ) => v
  case _ => ""
  }
))

val isActives = list.map(x => ((x\"is_active").validate[String] match {
  case JsSuccess(v, p ) => v
  case _ => ""
  }
))

val completeness = list.map(x => ((x\"completeness").validate[String] match {
  case JsSuccess(v, p ) => v
  case _ => ""
  }
))

// need to know in advance what is your max length of your tuple (tmax)
//  since 3rd value "completeness" can be missing, so we just take "" instead
val tmax = 3 
val res = for(idx <-0 to tmax-1) yield (names(idx),isActives(idx),completeness(idx))
res.toList
// List[(String, String, String)] = List((English,true,asdf), (Latin,asdf,232), (Latin,0009,""))

play json框架也有很好的文档,自己去看看吧:https ://www.playframework.com/documentation/2.8.x/ScalaJson


推荐阅读