解析嵌套的json结构

时间:2020-01-07 06:20:15

标签: json scala

我有一个嵌套的json文件,如下所示

{
    "Message No": 1.0,
    "abc": {
        "action": {
            "ab1": false,
            "ab2": false
        },
        "val": "Global"
    },

    "tyu": {
        "lmp": [{
            "Currency": "USD",
            "Amount": "32401.32"
        }]
    },

    "Payments": {
        "Array": ["Hi", "There"],
        "Details": [{
            "Date": "2019-04-11"
        }]
    }
}

我从Google找到了一段代码,可以将其转换为简单的键值对 代码如下所示

def Simply(m: Map[String, Any], tree: List[String] = List()) : Iterable[(String, Any)] = m.flatten
  {
    case (k: String, v: Map[String, Any] @unchecked) => Simply(v, tree :+ k)
    case (k: String, v: List[Map[String, Any]] @unchecked) => v.flatten(Simply(_, tree :+ k))
    case (k: String, v: Any) => List((tree :+ k.toString).mkString("_") ->v)
    case (k,null) => List((tree :+ k.toString).mkString("_") ->"null")

  }

代码工作正常,但无法处理json中的Array元素

“数组”:[“嗨”,“那里”],

我尝试提出

之类的额外条件
case (k: String, v: List[String]) => List((tree :+ k.toString).mkString("_") ->v.mkString(","))

但是这种情况阻止了简单函数中的以下情况

case (k: String, v: List[Map[String, Any]] @unchecked) => v.flatten(Simply(_, tree :+ k))

请帮助我理解,如果我将条件放置在错误的地方或需要做的任何代码更改

预期产量

(tyu_lmp_Amount,32401.32)
(abc_action_ab1,false)
(Message No,1.0)
(abc_action_ab2,false)
(tyu_lmp_Currency,USD)
(Payments_Details_Date,2019-04-11)
(Payments_Array,{Hi, There})
(abc_val,Global)

1 个答案:

答案 0 :(得分:0)

我希望这就是你想要的:

package advanced

import org.json4s._
import org.json4s.jackson.JsonMethods._

object JsonTest extends App {

  val s =
    """
      |{
      |    "Message No": 1.0,
      |    "abc": {
      |        "action": {
      |            "ab1": false,
      |            "ab2": false
      |        },
      |        "val": "Global"
      |    },
      |
      |    "tyu": {
      |        "lmp": [{
      |            "Currency": "USD",
      |            "Amount": "32401.32"
      |        }]
      |    },
      |
      |    "Payments": {
      |        "Array": ["Hi", "There"],
      |        "Details": [{
      |            "Date": "2019-04-11"
      |        }]
      |    }
      |}
      |""".stripMargin


  def jsonStrToMap(jsonStr: String): Map[String, Any] = {
    implicit val formats = org.json4s.DefaultFormats

    parse(jsonStr).extract[Map[String, Any]]
  }

  def Simply(m: Map[String, Any], tree: List[String] = List()) : Iterable[(String, Any)] = m.flatMap {
      case (k: String, v: Map[String, Any]) => Simply(v, tree :+ k)
      case (k: String, v: List[Any]) if v.headOption.exists(_.isInstanceOf[Map[String, Any]]) => v.flatMap{ subNode =>
        Simply(subNode.asInstanceOf[Map[String, Any]], tree :+ k)
      }
      case (k: String, v: List[String]) => List((tree :+ k.toString).mkString("_") -> v.mkString(","))
      case (k: String, v: Any) => List((tree :+ k.toString).mkString("_") ->v)
      case (k,null) => List((tree :+ k.toString).mkString("_") ->"null")

    }

  val map = jsonStrToMap(s)
  println(Simply(jsonStrToMap(s)))

  //
  // Map(tyu_lmp_Amount -> 32401.32, abc_action_ab1 -> false, Message No -> 1.0, abc_action_ab2 -> false, tyu_lmp_Currency -> USD, Payments_Details_Date -> 2019-04-11, Payments_Array -> Hi,There, abc_val -> Global)
  //
}

[Any]上的模式匹配将在模式匹配情况下尝试将其强制转换为任何类型,以使v: List[String]吞噬作为对象列表的任何子节点。