Scala, Circe, Json — как удалить родительский узел из json?

#json #scala #scala-cats #circe

Вопрос:

У меня есть структура json, подобная этой:

 "data" : {
  "fields": {
    "field1": "value1",
    "field2": "value2"
  }
}
 

Теперь я хотел бы удалить fields узел и сохранить данные в data :

 "data" : {
   "field1": "value1",
   "field2": "value2"
 }
 

Я пытался сделать это вот так:

 val result = data.hcursor.downField("fields").as[JsonObject].toOption.head.toString
 

но я получил странный результат, а не просто json в строковом формате

Я тоже пытался:

 val result = data.hcursor.downField("fields").top.head.toString
 

но это было то же самое, что:

 val result = data.toString
 

и это включает fields в себя .

Как я должен изменить свой код, чтобы удалить fields root и сохранить данные в data свойстве?

Комментарии:

1. Я не вижу здесь никаких операций модификации, только чтение. Вы отправили весь код, который хотели?

Ответ №1:

Вот полное рабочее решение, которое пересекает JSON, извлекает поля, удаляет их, а затем объединяет их в data :

 import io.circe.Json
import io.circe.parser._

val s =
  """
    |{
    |"data": {
    |  "fields": {
    |    "field1": "value1",
    |    "field2": "value2"
    |  }
    |}
    |}
    |""".stripMargin

val modifiedJson =
  for {
    json <- parse(s)
    fields <- json.hcursor
                .downField("data")
                .downField("fields")
                .as[Json]
    modifiedRoot <- json.hcursor
                      .downField("data")
                      .downField("fields")
                      .delete
                      .root
                      .as[Json]
    res <-
      modifiedRoot.hcursor
        .downField("data")
        .withFocus(_.deepMerge(fields))
        .root
        .as[Json]
  } yield res
 

Доходность:

 Right({
  "data" : {
    "field1" : "value1",
    "field2" : "value2"
  }
})