2015-04-14 61 views
0

因爲有一段時間我正在鬼混下面的問題。玩框架Json變換遞歸

我嘗試通過樹狀json結構進行遞歸轉換。

{ 
    "id": 21, 
    "title": "Title1", 
    "children": [ 
     { 
      "id": 22, 
      "title": "Title1.1", 
      "children": [ 
       { 
        "id": 33, 
        "title": "Title1.1.1", 
        "children": [ 
         { 
          "id": 41, 
          "title": "Title1.1.1.1", 
          "children": [ 
           { 
            "id": 42, 
            "title": "Title1.1.1.1.1", 
           } 
          ] 
         } 
        ] 
       } 
      ] 
     } 
    ] 
} 

到目前爲止,我有:

val idChanger:Reads[JsObject] = (__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)}) 

    val childPicker:Reads[JsValue] = (__ \ 'children).json.pick[JsArray].map{ 
    case JsArray(arr) => JsArray(arr.map(o => { 
     o.transform(idChanger) match { 
     case JsSuccess(value, jsPath) => 
      println(s"Success:$value") 
      value 
     case JsError(errors) => 
      println(s"Error:$errors"); JsNull 
     } 
    })) 
    } 

val jsvalue: JsValue = ... 
jsvalue.transform(childPicker) 
... 

這隻至今工作在第一級,並相應地改變ID「21」,而不是休息。

我嘗試了很多不同的方法來讓其他孩子也能夠遞歸地完成,但迄今爲止還沒有成功。

任何幫助這一個將不勝感激。

乾杯,羅布。

+0

它是如何失敗? – Ryan

+0

嗨,它不會失敗,但我只是沒有得到遞歸工作(在上面的代碼中沒有遞歸,但這是我用來獲取遞歸的基礎)。解決方案可能完全不同,上述方法完全錯誤,但我沒有其他想法。至今。 – Rob

回答

1

只需在您的Reads中添加遞歸調用,並確保處理JsArray以及JsObject。這是一個適合這個基本思想的簡單例子。

val idChanger: Reads[JsObject] = 
    (__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)}) 


val picker: Reads[JsValue] = __.json.pick.map{ 
    case JsArray(arr) => JsArray(arr.map(_.transform(picker).get)) 
    case v: JsValue => 
    v.transform(
     idChanger andThen (__ \ "children").json.update(picker) orElse 
     idChanger 
).get 
} 
+0

感謝您的答案,作品像魅力;-) – Rob