/ / Json-Werte mit Json4s für einen Json-Pfad aktualisieren - Scala, Json4s

update Json-Werte mit Json4s für einen JSON-Pfad - Scala, Json4s

Ich möchte die Json-Werte in meinem Json aktualisieren. Ich habe versucht, Transformationsfeld und Methoden zu ersetzen, aber jede hat ein Problem, das mich blockiert. Ich suche also Hilfe. Ich muss eine Methode erstellen, die ein List-of-Map-Argument akzeptiert. Der Schlüssel in dieser Map entspricht dem Json-Pfad und der Wert ist der zu aktualisierende Wert, zum Beispiel:

def jsonFieldUpdater( SeaarchKey :  List(Map(key, VALUE ) )

Also in der Map habe ich gerne einen Json Path [Innerage 30], der als Schlüssel fungiert; Meine Methode liest es und aktualisiert dieses Feld nicht alle Altersschlüssel. Siehe unteres Beispiel

{"name":"luca", "id": "1q2w3e4r5t", "age": 26, "inner": { "age": 27 }, "url":"http://www.nosqlnocry.wordpress.com"}

Ich bin hier etwas festgeklemmt, als ob ich die Use Transformfield-Methode verwende. Es aktualisiert alle Werte, die den Schlüssel haben, während das Alter vorhanden ist. Mein Codeblock ist:

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
object Json4sTest {
def main(arg: Array[String]) {
//val source = scala.io.Source.fromFile("file.txt")
//val lines = try source.mkString finally source.close()
var json = parse("""{"name":"luca", "id": "1q2w3e4r5t", "age": 26, "inner": { "age": 27 }, "url":"http://    www.nosqlnocry.wordpress.com"}""")
println(pretty(json))
//JObject(List(JField("foo", JObject(List(JField("bar", JInt(1))))))).replace("foo" :: "bar" :: Nil, JString("baz"))
json = json.replace("inner" :: "age" :: Nil, 29)
json = json transformField {
case ("name", _) => ("NAME", JString("Tuca"))
case ("age", JInt(age)) => ("age", JInt(age+1))
//case ("checkIn", date) => ("checkIn", JString(df.print(now.plusDays(deltaIn))))
}
println(pretty(json))

}
}

Ich bin auf die Ersatzmethode gestoßen, die das tutdie Aufgabe, einen Wert zu ersetzen. Aber dann sieht es so aus: json = json.replace ("inneres" :: "age" :: Nil, 29) Ich kann mir nicht vorstellen, wie ich mich an dieses Format anpassen kann, wenn ich nur eine Karte mit einem Json-Pfad und einem zu aktualisierenden Wert erhalte. Eine andere Idee, um das gleiche zu erreichen?

Ich habe die Lösung von n4to4 ausprobiert, aber da ich die Zuweisung von Map-Liste zu einer Variablen mache, erhalte ich den Fehler, zum Beispiel:

val a = List(Map("inner/age" -> 35, "age" -> 27, "name" -> "foo"))
jsonFieldUpdater(json, a )
// error : type mismatch; found :    List[scala.collection.immutable.Map[String,Any]] required: List[Map[String,org.json4s.JValue]] (which expands to) List[Map[String,org.json4s.JsonAST.JValue]]

Antworten:

2 für die Antwort № 1

Es muss nicht sein List von Map wahrscheinlich...?

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._

object Json4sTest {
def main(arg: Array[String]) {
var json = parse("""{"name":"luca", "id": "1q2w3e4r5t", "age": 26, "inner": { "age": 27 }, "url":"http://    www.nosqlnocry.wordpress.com"}""")
println(pretty(json))

val a: List[Map[String, JValue]] = List(Map("inner/age" -> 35, "age" -> 27), Map("name" -> "foo"))
val r = jsonFieldUpdater(json, a)
println(pretty(r))

val b = List(Updater("inner/age", 35), Updater("age", 27), Updater("name", "foo"))
val s = jsonFieldUpdater2(json, b)
println(pretty(s))
}

def jsonFieldUpdater(json: JValue, list: List[Map[String, JValue]]): JValue =
list.foldLeft(json) { case (json, kvs) =>
kvs.foldLeft(json) { case (json, (key, value)) =>
json.replace(key.split("/").toList, value)
}
}

case class Updater(key: String, value: JValue) {
def path: List[String] = key.split("/").toList
}

def jsonFieldUpdater2(json: JValue, list: List[Updater]): JValue =
list.foldLeft(json) { case (json, u) =>
json.replace(u.path, u.value)
}
}