/ / zaktualizuj wartości jsona json4s dla ścieżki json - scala, json4s

zaktualizuj wartości json z json4s dla ścieżki json - scala, json4s

Chcę zaktualizować wartości jsona w moim Jsonie. Próbowałem użyć pola transformacji i zastąpić metody, ale każdy ma problem, który blokuje mi kontynuowanie. Więc szukam pomocy. Muszę stworzyć metodę, która pobiera argument List of Map, klucz w tej Mapie odpowiada ścieżce Json, a wartością jest wartość, która ma być aktualizowana, na przykład:

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

Więc na mapie mam ścieżkę Jsona [wewnętrzny, 30], który działa jak klucz; moja metoda odczytuje go i aktualizuje to pole nie wszystkie klucze wieku. Zobacz poniższy przykład

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

Jestem tu trochę zablokowany, ponieważ jeśli użyję metody Use transformfield, to aktualizuje wszystkie wartości, które mają klucz jako wiek, nie chcę, aby chciałem przejść do konkretnej ścieżki i przekształcić ją. Mój blok kodu to:

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))

}
}

Natknąłem się na metodę zastępowania, która to robizadanie zastąpienia wartości. Ale wtedy wygląda tak: json = json.replace („inner” :: „age” :: Nil, 29) Nie jestem w stanie myśleć, jak mogę dostosować się do tego formatu, gdy otrzymuję mapę, która ma ścieżkę Jsona i wartość, która musi zostać zaktualizowana. Jakikolwiek inny pomysł na osiągnięcie tego samego?

Wypróbowałem rozwiązanie za pomocą n4to4, ale gdy wykonuję przypisanie listy map do zmiennej, otrzymuję błąd, na przykład:

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]]

Odpowiedzi:

2 dla odpowiedzi № 1

To nie musi być List z Map prawdopodobnie...?

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)
}
}