2013-10-01 12 views
6

は、以下のJSONを検討し、適切な場所に追加する:リフトJSONを使用して、今リフトjsonの操作 -

{ 
    "type":"A1", 
    "system":{ 
    "path":"/example.org/FooBar", 
    "lastModified":"2013-10-01T12:00:00Z" 
    }, 
    "fields":{ 
    "foo1":["bar1"], 
    "foo2":["bar2"], 
    "foo3":["bar3"] 
    } 
} 

を、私はにこのJSONを変更したい:そう

{ 
    "type":"A1", 
    "system":{ 
    "path":"/example.org/FooBar", 
    "lastModified":"2013-10-01T12:00:00Z" 
    }, 
    "fields":{ 
    "foo1":["bar1"], 
    "foo2":["bar2"], 
    "foo3":["bar3"] 
    }, 
    "injected":{ 
    "bar1":"foo1", 
    "bar2":"foo2" 
    } 
} 

、I次のことを試してみました:

scala> val json = parse(""" 
    |{ 
    | "type":"A1", 
    | "system":{ 
    | "path":"/example.org/FooBar", 
    | "lastModified":"2013-10-01T12:00:00Z" 
    | }, 
    | "fields":{ 
    | "foo1":["bar1"], 
    | "foo2":["bar2"], 
    | "foo3":["bar3"] 
    | } 
    |}""") 

json: net.liftweb.json.JValue = JObject(List(JField(type,JString(A1)), JField(system,JObject(List(JField(path,JString(/example.org/FooBar)), JField(lastModified,JString(2013-10-01T12:00:00Z))))), JField(fields,JObject(List(JField(foo1,JArray(List(JString(bar1)))), JField(foo2,JArray(List(JString(bar2)))), JField(foo3,JArray(List(JString(bar3))))))))) 

scala> json transform{case JObject(l) => JObject(l ::: List(JField("injected", ("bar1" -> "foo1") ~ ("bar2" -> "foo2"))))} 
res0: net.liftweb.json.JsonAST.JValue = JObject(List(JField(type,JString(A1)), JField(system,JObject(List(JField(path,JString(/example.org/FooBar)), JField(lastModified,JString(2013-10-01T12:00:00Z)), JField(injected,JObject(List(JField(bar1,JString(foo1)), JField(bar2,JString(foo2)))))))), JField(fields,JObject(List(JField(foo1,JArray(List(JString(bar1)))), JField(foo2,JArray(List(JString(bar2)))), JField(foo3,JArray(List(JString(bar3)))), JField(injected,JObject(List(JField(bar1,JString(foo1)), JField(bar2,JString(foo2)))))))), JField(injected,JObject(List(JField(bar1,JString(foo1)), JField(bar2,JString(foo2))))))) 

scala> Printer.pretty(render(res0)) 
res1: String = 
{ 
    "type":"A1", 
    "system":{ 
    "path":"/example.org/FooBar", 
    "lastModified":"2013-10-01T12:00:00Z", 
    "injected":{ 
     "bar1":"foo1", 
     "bar2":"foo2" 
    } 
    }, 
    "fields":{ 
    "foo1":["bar1"], 
    "foo2":["bar2"], 
    "foo3":["bar3"], 
    "injected":{ 
     "bar1":"foo1", 
     "bar2":"foo2" 
    } 
    }, 
    "injected":{ 
    "bar1":"foo1", 
    "bar2":"foo2" 
    } 
} 

とあなたが見ることができるように、injected部分は、fieldsに加え、systemも同様である。 これをrootの下に一度追加したかっただけです。

だから私は間違っているのですか?どのように私は必要な正しい構造にjsonを変換することができますか?

答えて

5

問題は、変換内で定義された部分関数がjson構造内のすべての可能なレベルで一致していることです。外側のJObjectの「システム」と「フィールド」コンポーネントは、それ自体がJObjectsなので、部分的な関数に一致し、変換されます。

あなたが求めている結果を取得するには、例えば、マッチはより具体的にする必要があります。

それが「タイプ」を設定したことを最も外側のオブジェクト(ここでは、に関するいくつかのユニークな情報を使用して
json transform {case JObject(fields) if (fields contains JField("type", "A1")) => 
    JObject(l ::: ... 

"A1")。また

は、リフトJSONは、私が扱っていないマージ機能を持っていますが、これはあなたが望むものを与えるかもしれない:あなたは、単一の場所、 transform ISN」においてフィールドを追加する必要がある場合

json merge JObject(JField("injected", ...) :: Nil) 
+0

ありがとうございます!マージは偉大な仕事をし、私が望むものを正確に私に与えました。 –

4

最高の工具T-あなただけの代わりに~を使用することができます。

val newJson = json match { 
    case obj: JObject => 
    obj ~ ("injected" -> ("bar1" -> "foo1") ~ ("bar2" -> "foo2")) 
    case _ => throw new RuntimeException("Did not receive a JSON object!") 
} 

あなたは常にオブジェクトを解析するだろうという事実を知っている場合、あなたはJObjectjsonをキャストし、ここでのマッチング事業を避けることができます。

+0

私はいつも 'parse'を使っているとは限りません。デモのためだけのものでした。 –

関連する問題