将Json Array转换为Scala列表的最佳方法是什么,并且Json列表也是JsonObject的列表,并且它们在我的Scala代码中没有任何类,我不需要它,只有我的简单json字符串
val jsonData = """{
| "store": {
| "book": [
| {
| "category": "reference",
| "author": "Nigel Rees",
| "title": "Sayings of the Century",
| "price": 8.95
| },
| {
| "category": "fiction",
| "author": "Evelyn Waugh",
| "title": "Sword of Honour",
| "price": 12.99
| },
| {
| "category": "fiction",
| "author": "Herman Melville",
| "title": "Moby Dick",
| "isbn": "0-553-21311-3",
| "price": 8.99
| },
| {
| "category": "fiction",
| "author": "J. R. R. Tolkien",
| "title": "The Lord of the Rings",
| "isbn": "0-395-19395-8",
| "price": 22.99
| }
| ],
| "bicycle": {
| "color": "red",
| "price": 19.95
| }
| },
| "expensive": 10
|}""".stripMargin
并且我输入了json
{ "hello": "$.store.book[?(@.price < 10)]" }
表示从满足此条件的json列表中获取
我班上有我需要做的所有事情:
class CustomConductor {
def extractRequiredObject[T](jsonString: String)(implicit m: Manifest[T]): T = {
extractFrom(jsonString) match {
case Success(jsonParsed) =>
jsonParsed
case Failure(exc) =>
throw new IllegalArgumentException(exc)
}
}
def parsing(headerData: mutable.Map[String, String], jobData: String): Map[String, Any] = {
var t: Map[String, Any] = Map()
headerData.foreach{data: (String, Any) =>
t += (data._1 -> recurse(parse(data._2.toString).values.asInstanceOf[Map[String, Any]], jobData, data._2.toString))
}
t
}
private def recurse(m: Map[String, Any], data: String, myMap: String): Map[String, Any] = {
def helper(m: Map[String, Any]): Map[String, Any] = {
var b = m
m.foreach(k => {
k._2 match {
case str: String if str.startsWith("$") =>
val res = getDataByJsonPath(data, k._2.toString)
if (res != null) {
// here I want to check if res is JsonArray of object convert it to List of Map
// if (res.isInstanceOf[JSONArray]) {
// val json = parse(res.toString)
// for (elem <- json.children) {
// println(elem)
// }
// b += (k._1 -> json.children.toList)
// }
b += (k._1 -> res)
}
case map: Map[String, Any] =>
b += (k._1 -> helper(map))
case _ =>
}
})
b
}
helper(m)
}
private def extractFrom[T](jsonString:String)(implicit m: Manifest[T]): Try[T] = {
implicit val formats: DefaultFormats.type = DefaultFormats
Try {
parse(jsonString).extract[T]
}
}
private def getDataByJsonPath(jsonString: String, jsonPath: String): Any = {
val a = JsonPath.read[Any](jsonString, jsonPath)
if (a.isInstanceOf[JSONArray]) {
JsonPath.read[List[Any]](jsonString, jsonPath)
}else
a
}
}
转换为地图可以正常工作,但是如您所见,hello值未在JsonArray中列出它
Map(hello->[
{
"author": "Nigel Rees",
"price": 8.95,
"category": "reference",
"title": "Sayings of the Century"
},
{
"author": "Herman Melville",
"price": 8.99,
"isbn": "0-553-21311-3",
"category": "fiction",
"title": "Moby Dick"
}
])))
如果没有并且不需要将其映射到案例类,则可以使用我知道的最简单的库ujson
。
更多信息:http://www.lihaoyi.com/post/uJsonfastflexibleandintuitiveJSONforScala.html
标准用例类方法在您的用例中就足够了。我个人更喜欢lift-json作为JSON解析用例。您可以尝试以下操作:
case class Root(store:Store,expensive:Int)
case class Store(book:List[Book],bicycle:Bicycle)
case class Book(category:String,author:String,title:String,isbn:Option[String],price:Double)
case class Bicycle(color:String,price:Double)
import net.liftweb.json.{parse,Formats}
object Main{
implicit val formats:Formats = DefaultFormats
val data:String = """{
| "store": {
| "book": [
| {
| "category": "reference",
| "author": "Nigel Rees",
| "title": "Sayings of the Century",
| "price": 8.95
| },
| {
| "category": "fiction",
| "author": "Evelyn Waugh",
| "title": "Sword of Honour",
| "price": 12.99
| },
| {
| "category": "fiction",
| "author": "Herman Melville",
| "title": "Moby Dick",
| "isbn": "0-553-21311-3",
| "price": 8.99
| },
| {
| "category": "fiction",
| "author": "J. R. R. Tolkien",
| "title": "The Lord of the Rings",
| "isbn": "0-395-19395-8",
| "price": 22.99
| }
| ],
| "bicycle": {
| "color": "red",
| "price": 19.95
| }
| },
| "expensive": 10
|}""".stripMargin
val parsedJson:Root = parse(data)
.extractOpt[Root]
.getOrElse(throw new Exception("Malformed JSON"))
println(parsedJson.store.)
}