Eksperymentuję z biblioteką json4s (opartą na lift-json). Jedną z rzeczy, które chciałbym zrobić, to przetworzyć łańcuch JSON w AST, a następnie nim manipulować.Jak manipulować JSON AST w Scala
Na przykład, chciałbym wstawić pole (wstawić pole do AST, jeśli nie istnieje, lub zaktualizować jego wartość, jeśli to robi).
Nie znalazłem sposobu, jak to zrobić w dokumentacji. Eksperymentując z dostępnymi metodami, wymyśliłem następujące, które działa, ale czuję się niezdarny.
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
object TestJson {
implicit val formats = DefaultFormats
def main(args: Array[String]): Unit = {
val json = """{"foo":1, "bar":{"foo":2}}"""
val ast = parse(json).asInstanceOf[JObject]
println(upsertField(ast, ("foo" -> "3")))
println(upsertField(ast, ("foobar" -> "3")))
}
def upsertField(src:JObject, fld:JField): JValue = {
if(src \ fld._1 == JNothing){
src ~ fld
}
else{
src.replace(List(fld._1), fld._2)
}
}
}
Nie lubię go z wielu powodów:
- Mając jawnie rzucić wyniki
parse(json)
doJObject
- Wynikiem funkcji
upsertField
jestJValue
, które będę musiał przekształcenie jeśli Chcę manipulować obiektem dalej - Funkcja po prostu wydaje się bardzo nieelegancka
- Nie działa dla pól, które nie znajdują się na najwyższym poziomie hierarchii.
Czy istnieje lepszy sposób na przekształcenie AST?
EDIT: jako obejście problemu, udało mi się przekształcić moje JSON do Scala regularnych zajęć i manipulować nimi z obiektywami (Using Lenses on Scala Regular Classes)
co ma AST kandydowania? –
@QuyTang AST oznacza "abstrakcyjne drzewo składniowe" – Eduardo
Dzięki @Eduardo –