Scala воспроизводит JSON, ищет и сопоставляет определенное поле с нулевым значением - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть следующий блок Json, который я возвратил как JsObject

{
  "first_block": [
    {
      "name": "demo",
      "description": "first demo description"
    }
  ],
  "second_block": [
    {
      "name": "second_demo",
      "description": "second demo description",
      "nested_second": [
        {
          "name": "bob",
          "value": null
        },
        {
          "name": "john",
          "value": null
        }
      ]
    }
  ]
}

Из этого я хочу вернуть список всех возможных значений, которые я мог бы иметь во втором блоке, вложенноммассив для имени и значения.так с приведенным выше примером List([bob,null],[john,null]) или что-то в этом духе.

Проблема, с которой я столкнулся, заключается в том, что секция значений понимает нулевые значения.Я пытался сопоставить его и вернуть строку "null", но не могу найти ее для совпадения со значениями Null.

Что было бы для меня лучшим способом вернуть имя и значения вмассив nested_second.

Я пытался использовать case-классы и readAsNullable безуспешно, и моя последняя попытка пошла по следующим направлениям:

val secondBlock = (jsObj \ "second_block").as[List[JsValue]]

secondBlock.foreach(nested_block => {
  val nestedBlock = (nested_block \ "nested_second").as[List[JsValue]]
  nestedBlock.foreach(value => {
    val name = (value \ "name").as[String] //always a string
    var convertedValue = ""
    val replacement_value = value \ "value"
    replacement_value match {
      case JsDefined(null) => convertedValue = "null"
      case _ => convertedValue = replacement_value.as[String]
    }

    println(name)
    println(convertedValue)
  })
}
)

Кажется, convertedValue возвращается как 'JsDefined (null)' независимо, и я уверен, что то, как я это делаю, ужасно плохо.

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

С play-json Я использую всегда case-classes!

Я упростил вашу проблему до сути:

import play.api.libs.json._

val jsonStr = """[
        {
          "name": "bob",
          "value": null
        },
        {
          "name": "john",
          "value": "aValue"
        },
        {
          "name": "john",
          "value": null
        }
      ]"""

Определите класс кейса

case class Element(name: String, value: Option[String])

Добавьте форматер в компаньон object:

object Element {
  implicit val jsonFormat: Format[Element] = Json.format[Element]
}

Использование validate:

Json.parse(jsonStr).validate[Seq[Element]] match {
  case JsSuccess(elems, _) => println(elems)
  case other => println(s"Handle exception $other")
}

Это возвращает: List(Element(bob,None), Element(john,Some(aValue)), Element(john,None))

Теперь вы можете сделатьвсе, что вы хотите с values.

0 голосов
/ 23 ноября 2018

Замените JsDefined(null) на JsDefined(JsNull).

Возможно, вы запутались, потому что println(JsDefined(JsNull)) печатается как JsDefined(null).Но это не так, как представляется значение null поля JSON.null представляется как объект case JsNull.Это просто хороший дизайн API, где возможные случаи представлены иерархией классов:

enter image description here

...