Как получить ключи и значения при разборе Json с помощью Scala-Play Json Framework?

У меня есть файл json, в котором есть несколько ключей и значений. Мне нужно проанализировать Json и распечатать ключи и их значения. Например, файл json выглядит следующим образом. Я хочу напечатать это как ключи и значения

{
   "Parcer":[
      {
         "key":"0203",
         "value":{
                  "Encryption":
                               {
                                 "enabled":"yes",
                                 "encryption_type":"base64",
                                 "key":"334848484",
                                 "return":"name"
                                 }
                  }
      },
      {
         "key":"0405",
         "value":{
            "Encryption":
                        {
                           "enabled":"yes",
                           "encryption_type":"base64",
                           "key":"334848484",
                           "return":"none"
                        },
            "Parcer":[
                        {
                           "key":"0102",
                           "value":"humidity"
                        },
                        {
                           "key":"0304",
                           "value":{
                                    "Encryption":{
                                                   "enabled":"yes",
                                                   "encryption_type":"SHA1",
                                                   "key":"1211212",
                                                       "return":"none"
                                                }
                                        }
                            }
                         ]

                }
          }],
  }```


person Ashok v    schedule 02.04.2019    source источник


Ответы (1)


Самый простой способ — создать case class, например:

case class MyObj(header:String, value: Seq[Map[String, String]])

Затем вам просто нужно добавить одну строку для сортировки, например:

import play.api.libs.json._

object MyObj {
  implicit val jsonFormat: OFormat[MyObj] = Json.format[MyObj]
}

Теперь у вас есть хороший case class, с которым вы можете работать:

  val json =
    Json.parse(
      """{
   "header" : "header value",
   "value" : [
        {
         "a" : "a_val",
         "b" : "b_val",
         "c" : "c_val"
        },
        {
        "a" : "a_val",
         "b" : "b_val",
         "c" : "c_val"
        }
     ]
}""")

Вот пример, как получить все "a".

  json.validate[MyObj] match {
    case JsSuccess(myObj, _) =>

      val allAs =myObj.value.flatMap(m => m.get("a").toSeq)
      println(allAs) // >> Vector(a_val, a_val)
    case e:JsError => // handle error
  }

Это дает вам:

json.validate[MyObj] возвращает JsSuccess(MyObj(header value,Vector(Map(a -> a_val, b -> b_val, c -> c_val), Map(a -> a_val, b -> b_val, c -> c_val))),)

println возвращает: Vector(a_val, a_val)

Это описано здесь, в документации: автоматическое сопоставление JSON

person pme    schedule 02.04.2019
comment
Если значения внутри value не всегда являются строками (какое ужасное предложение...), карту можно изменить на value: Seq[Map[String, Any]]. Можно подумать :-) - person James Whiteley; 02.04.2019
comment
Как мы обрабатываем вложенные значения в a? - person Ashok v; 02.04.2019
comment
Вместо a мы можем указать JsPath? - person Ashok v; 02.04.2019
comment
тогда вам не нужно сначала переводить его на case class - но я не могу вам помочь, потому что я всегда использую способ, который я показал вам в своем ответе - person pme; 02.04.2019
comment
Отредактировал мой вопрос и проверил ваш ответ с помощью этого json. Но это не сработало. Я новичок в скале. Извините за ошибки. - person Ashok v; 02.04.2019
comment
это более сложная структура - тогда в вашем первоначальном вопросе - person pme; 02.04.2019
comment
лучшее, что вы можете сделать - это отменить свое изменение - затем проверить, работает ли мое решение для него - если это так, примите его и задайте другой вопрос с более точным примером (например, отредактированной версией) - в противном случае я должен удалить свой ответ; ( - person pme; 02.04.2019
comment
Я искал способ сделать что-то подобное, и многие другие вопросы SO на первой странице Google утверждают, что в Play нет встроенного чтения для карт. Они, правда, старше. Можем ли мы добавить ссылку на документацию и/или примечания к изменениям, добавляющие эту функциональность? - person Mystagogue; 26.04.2019
comment
@Mystagogue - я поправил свой ответ - спасибо за подсказку - person pme; 26.04.2019
comment
@pme Я не уверен, что добавленная вами ссылка действительно содержит соответствующую информацию. Нет никаких указаний на то, что Play изначально обрабатывает Map на этой странице. Просматривая исходный код, я обнаружил, что у них есть специальный случай для работы с Картами, который, я ожидаю, будет где-то задокументирован. - person Mystagogue; 26.04.2019