Как вставить пустой объект в JSON с помощью Circe? - PullRequest
0 голосов
/ 29 декабря 2018

Я получаю объект JSON по сети в виде строки.Я тогда использую Цирцею, чтобы разобрать это.Я хочу добавить несколько полей к нему, а затем передать его в нисходящий поток.

Почти все это работает.

Проблема в том, что мое "добавление" действительно "перезаписывает".Это на самом деле нормально, пока я сначала добавляю пустой объект.Как я могу добавить такой пустой объект?

Итак, взглянув на код ниже, я перезаписываю "иногда_эмпты: {}", и это работает.Но так как иногда не всегда пусто, это приводит к некоторой потере данных.Я хотел бы добавить поле, например: "custom: {}", а затем переписать значение custom с моим существующим кодом.

Были полезны две публикации StackOverflow.Один работал, но не совсем то, что я искал.Другой, который я не смог заставить работать.

1: Изменение массива JSON в Scala с помощью circe

2: Добавление поля в json с использованием Circe

val js: String = """
{
  "id": "19",
  "type": "Party",
  "field": {
    "id": 1482,
    "name": "Anne Party",
    "url": "https"
  },
  "sometimes_empty": {

  },
  "bool": true,
  "timestamp": "2018-12-18T11:39:18Z"
}
"""

val newJson = parse(js).toOption
  .flatMap { doc =>
    doc.hcursor
      .downField("sometimes_empty")
      .withFocus(_ =>
        Json.fromFields(
          Seq(
            ("myUrl", Json.fromString(myUrl)),
            ("valueZ", Json.fromString(valueZ)),
            ("valueQ", Json.fromString(valueQ)),
            ("balloons", Json.fromString(balloons))
          )
        )
      )
      .top
  }

newJson match {
  case Some(v) => return v.toString
  case None => println("Failure!")
}

1 Ответ

0 голосов
/ 29 декабря 2018

Нам нужно сделать пару вещей.Во-первых, нам нужно увеличить конкретное свойство, которое мы хотим обновить, если оно не существует, мы создадим новое пустое.Затем мы превращаем увеличенное свойство в виде Json в JsonObject, чтобы можно было изменить его с помощью метода +:.Как только мы это сделаем, нам нужно взять обновленное свойство и заново ввести его в исходный проанализированный JSON, чтобы получить полный результат:

import io.circe.{Json, JsonObject, parser}
import io.circe.syntax._

object JsonTest {
  def main(args: Array[String]): Unit = {
    val js: String =
      """
        |{
        |  "id": "19",
        |  "type": "Party",
        |  "field": {
        |    "id": 1482,
        |    "name": "Anne Party",
        |    "url": "https"
        |  },
        |  "bool": true,
        |  "timestamp": "2018-12-18T11:39:18Z"
        |}
      """.stripMargin

    val maybeAppendedJson =
      for {
        json <- parser.parse(js).toOption
        sometimesEmpty <- json.hcursor
          .downField("sometimes_empty")
          .focus
          .orElse(Option(Json.fromJsonObject(JsonObject.empty)))
        jsonObject <- json.asObject
        emptyFieldJson <- sometimesEmpty.asObject
        appendedField = emptyFieldJson.+:("added", Json.fromBoolean(true))
        res = jsonObject.+:("sometimes_empty", appendedField.asJson)
      } yield res

    maybeAppendedJson.foreach(obj => println(obj.asJson.spaces2))
  }
}

Выход:

{
  "id" : "19",
  "type" : "Party",
  "field" : {
    "id" : 1482,
    "name" : "Anne Party",
    "url" : "https"
  },
  "sometimes_empty" : {
    "added" : true,
    "someProperty" : true
  },
  "bool" : true,
  "timestamp" : "2018-12-18T11:39:18Z"
}
...