2014-02-15 5 views
2

주어진 다음의 JSON에플레이 프레임 워크 : 어떻게 ... JSON 트리

{ "id":"1234", 
    "name" -> "joe", 
    "tokens: [{ 
    "id":"1234", 
    "id":"2345" 
    }] 
} 

을 값의 모든 발생을 교체 ... 내가 좋아하는 xxxx에 의해 모든 id의 값을 교체해야 이 : 그럼

val json = Json.obj(
    "id" -> "1234", 
    "name" -> "joe", 
    "tokens" -> Json.arr(
    Json.obj("id" -> "1234"), 
    Json.obj("id" -> "2345") 
) 
) 

json: play.api.libs.json.JsObject = {"id":"1234","name":"joe","tokens":[{"id":"1234"},{"id":"2345"}]} 

모든 공을 받고 :

{ "id":"xxxx", 
    "name" -> "joe", 
    "tokens: [{ 
    "id":"xxxx", 
    "id":"xxxx" 
    }] 
} 

의이 JSON 트리를 만들 시작하자 1,239,의 아주 간단하다 :

이제
json \\ "id" 

res64: Seq[play.api.libs.json.JsValue] = List("1234", "1234", "2345") 

, 어떻게 xxxx에 의해 모든 id의 값을 대체 할 수 있습니까?

답변

6

하는 표준 재생 JSON 라이브러리를 함께 할 수있는 좋은 방법이있을 나타나지 않습니다 내가 비록 그 점에서 틀림없이 입증 될 수있어서 기쁩니다. 당신은, 그러나 그것은 쉽게 play-json-zipper 확장을 사용하여 수행 할 수 있습니다

def replaceValue(json: JsValue, key: String, replacement: String) = json.updateAll { 
    case (__ \ path, JsString(_)) if path == key => JsString(replacement) 
} 

json으로 지퍼 확장,하지만 당신이 아직도 "실험"하려는 경우 :

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

val json = Json.obj(
    "id" -> "1234", 
    "name" -> "joe", 
    "tokens" -> Json.arr(
    Json.obj("id" -> "1234"), 
    Json.obj("id" -> "2345") 
) 
) 

// Using `updateAll` we pattern match on a path (ignoring 
// the existing value, as long as it's a string) and replace it 
val transformed = json.updateAll { 
    case (__ \ "id", JsString(_)) => JsString("xxxx") 
} 

// play.api.libs.json.JsValue = {"id":"xxxx","name":"joe","tokens":[{"id":"xxxx"},{"id":"xxxx"}]} 

만들기 위해 재사용 가능한 기능이 프로젝트에 추가하면 project/Build.scala appDependencies에 다음을 추가

"play-json-zipper" %% "play-json-zipper" % "1.0" 

다음과 같은 해결을 :

,
"Mandubian repository releases" at "https://github.com/mandubian/mandubian-mvn/raw/master/releases/" 
+0

텍사스, 이미 시도 ...하지만 난 매개 변수로 키를 전달해야하고,이 경우는 작동하지 않습니다 : (: JsValue, 키 : 문자열 JSON) = json.update { 경우 (toXXXX 데프 (value) => JsString (value) } – j3d

+0

@ j3d : "작동하지 않는다"고 정의 할 수 있습니까? 키와 대체 값이 두 매개 변수 인 경우 예제를 추가했습니다. 주석에 올린 코드가 잘못되었습니다 ('updateAll'을 사용해야하고 기존 값을 원하는 대체 코드와 일치시킵니다.) – Mikesname

+0

Gasp, 당신의 코드가 완벽하게 작동합니다. 문제는 실제 예제가 더 복잡하다는 것입니다. 나는 방금 새로운 질문 [http://stackoverflow.com/questions/21801071/how-to-replace-all-the-values-with-the-same-key-in-a-json-tree]을 게시했습니다. 아직 지루하지 않다면, 빨리 볼 수 있습니다 ;-) – j3d

0

아마도 가장 효율적인 방법은 아니지만 JSON을 객체로 변환하여 새로운 필드로 복사 한 다음 json으로 다시 변환 해보십시오. 불행하게도 현재 내가 코드를 확인하기 위해 환경을 필요는 없지만이 같은이어야합니다

case class MyId(id: String) 
case class MyObject(id: String, name: String, tokens: List[MyId]) 

implicit val idFormat = Json.format[MyId] 
implicit val objectFormat = Json.format[MyObject] 

val json = Json.parse(jsonString) 
val jsResult = Json.fromJson[MyObject](json) 

val obj = jsResult match { 
     case JsSuccess(s, _) => s 
     case _ => throw new IllegalStateException("Unexpected") 
    } 

val newObj = obj.copy(id = "xxxx") 
val result = Json.toJson(newObj)