考虑以下json:
{ "type":"A1","system":{ "path":"/example.org/FooBar","lastModified":"2013-10-01T12:00:00Z" },"fields":{ "foo1":["bar1"],"foo2":["bar2"],"foo3":["bar3"] } }@H_301_3@现在,使用lift-json,我想将此json更改为:
{ "type":"A1","foo3":["bar3"] },"injected":{ "bar1":"foo1","bar2":"foo2" } }@H_301_3@所以,我尝试了以下内容:
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(2013-10-01T12:00:00Z)),JField(injected,JObject(List(JField(bar1,JString(foo1)),JField(bar2,JString(foo2)))))))),JArray(List(JString(bar3)))),JString(foo2))))))) scala> Printer.pretty(render(res0)) res1: String = { "type":"A1","lastModified":"2013-10-01T12:00:00Z","injected":{ "bar1":"foo1","bar2":"foo2" } },"foo3":["bar3"],"bar2":"foo2" } }@H_301_3@正如您所看到的,注入的部分被添加到字段和系统也是如此.
我只想在根目录下添加一次.那么,我做错了什么?如何将json转换为我需要的正确结构?
解决方法
您遇到的问题是转换中定义的部分函数在json结构中的所有可能级别上都匹配.由于外部JObject的“系统”和“字段”组件本身就是JObject,它们与部分函数匹配,并且也可以进行转换.
要获得您正在寻找的结果,您需要使匹配更具体,例如:
json transform {case JObject(fields) if (fields contains JField("type","A1")) => JObject(l ::: ...@H_301_3@使用关于最外层对象的一些独特信息(这里,它将“type”设置为“A1”).
另外,lift json有一个我没有处理的合并功能,但可能会提供你想要的东西:
json merge JObject(JField("injected",...) :: Nil)@H_301_3@