我正在通过网络获取一个JSON对象,它是一个字符串。然后,我使用Circe进行解析。我想向其中添加一些字段,然后将其传递给下游。
几乎所有方法都可以使用。
问题在于我的“添加”实际上是“覆盖”。只要我先添加一个空对象,实际上就可以了。如何添加这样的空对象?
因此,请看下面的代码,我正在覆盖“ sometimes_empty:{}”,它可以正常工作。但是,由于有时候Empty_empty并不总是空的,因此会导致一些数据丢失。我想添加一个字段:“ custom:{}”,然后用现有代码覆盖custom的值。
两个StackOverflow帖子很有帮助。一个工作,但不是我想要的。另一个我无法上班。
1:Modifying a JSON array in Scala with circe
2:Adding field to a json using 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!")
}
答案 0 :(得分:1)
我们需要做几件事。首先,我们需要放大要更新的特定属性,如果该属性不存在,我们将创建一个新的空属性。然后,我们将Json
形式的zoomed属性转换为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"
}