2014-10-10 55 views
4

我的眼睛是否在欺騙我,或者我可以不使用包含數組元素的JsPath更新嵌套節點? (例如,/ A/B(0)/ C)JsPath.json.update不適用於路徑中的數組元素(IdxPathNode)?

val pnJson = Json.parse("""{"a": {"b": [ {"c": { "d": 1 } } ] } } """)          
val pnJsPath = (__ \ "a" \ "b")(0) \ "c"                 
val pnTrans = pnJsPath.json.update (__.read[JsObject].map{ _ ++ Json.obj("e" -> 2)}) 

pnJson.transform(pnTrans) 

//結果:了java.lang.RuntimeException:預期KeyPathNode

如果我不能使用__ json.update,我怎樣才能。完成這個? 試圖用不變性來實現這一點。

回答

2

簡短的回答是you can't do that with JsPath。該票提到使用JsZipper庫作爲操縱JSON的更好方法。如果您選擇使用它,你可以這樣做:

scala> import play.api.libs.json.extensions._ 
import play.api.libs.json.extensions._ 

scala> import play.api.libs.json.monad.syntax._ 
import play.api.libs.json.monad.syntax._ 

scala> val pnJson = Json.parse("""{"a": {"b": [ {"c": { "d": 1 } } ] } } """) 
pnJson: play.api.libs.json.JsValue = {"a":{"b":[{"c":{"d":1}}]}} 

scala> val pnJsPath = (__ \ "a" \ "b")(0) \ "c" 
pnJsPath: play.api.libs.json.JsPath = /a/b(0)/c 

scala> pnJson.update(pnJsPath, _.set(__ \ "e" -> JsNumber(2))) 
res0: play.api.libs.json.JsValue = {"a":{"b":[{"c":{"d":1,"e":2}}]}} 

否則,最好的辦法就是要打破你的任務分爲兩個部分,第一部分是解析陣列和第二部分是把它變成一個新的數組修改內容。

+1

+1堅持遊戲人添加到他們的圖書館,而不是依靠JsZipper :) – 2014-10-12 05:21:35