【问题标题】:TransformField in JArray with json4s带有json4s的JArray中的TransformField
【发布时间】:2015-01-14 07:33:09
【问题描述】:

我正在尝试使用 Scala,特别是 json4s 库,以便操作一些 json。我对 Scala 和 json4s 的语法感到很困惑,我想问问你们。

我有这个 json,我需要更新一些字段,并将其完整地发送回服务。 json 看起来像这样:

{
    "id": "6804",
    "signatories": [
        {
            "id": "12125",
            "fields": [
                {
                    "type": "standard",
                    "name": "fstname",
                    "value": "John"
                },
                {
                    "type": "standard",
                    "name": "sndname",
                    "value": "Doe"
                },
                {
                    "type": "standard",
                    "name": "email",
                    "value": "john.doe@somwhere.com"
                },
                {
                    "type": "standard",
                    "name": "sigco",
                    "value": "Company"
                }
            ]
        }
    ]
}

我正在使用json4s 将其解析为 JArray,如下所示:

import org.json4s._
import org.json4s.native.JsonMethods._

val data = parse(json)
val fields = (data \ "signatories" \ "fields")

这给了我一个包含所有字段的 JArray:(非常抱歉格式化)

JArray(List(JObject(List((type,JString(standard)), (name,JString(fstname)), (value,JString(John)))), JObject(List((type,JString(standard)), (name,JString(sndname)), (value,JString(Doe)))), JObject(List((type,JString(standard)), (name,JString(email)), (value,JString(john.doe@somwhere.com)))), JObject(List((type,JString(standard)), (name,JString(sigco)), (value,JString(Company))))))

我现在面临的问题是:

如何找到每个字段属性“名称”,并将其更改(转换)为新值?

例如(我知道这很可能在 Scala 中不是这样工作的,但你会明白的)

foreach(field in fields) {
     if(field.name == 'fstname') {
          field.value = "Bruce"
     }
}

【问题讨论】:

标签: scala json4s


【解决方案1】:

你可以试试

val a = JArray(List(JObject(....))) // Same as your JArray<pre><code>   

a.transform {
 // Each JArray is made of objects. Find fields in the object with key as name and value as fstname
case obj: JObject => obj.findField(_.equals(JField("name", JString("fstname")))) match {
  case None => obj //Didn't find the field. Return the same object back to the array
  // Found the field. Change the value
  case Some(x) => obj.transformField { case JField(k, v) if k == "value" => JField(k, JString("Bruce")) } 
}
}    

结果 -


res0: org.json4s.JValue = JArray(List(JObject(List((typ,JString(standard)), (name,JString(fstname)), (value,JString(Bruce)))), JObject(List((typ,JString(standard)), (name,JString(sndname)), (
ring(Doe)))), JObject(List((typ,JString(standard)), (name,JString(email)), (value,JString(john.doe@somwhere.com)))), JObject(List((typ,JString(standard)), (name,JString(sigco)), (value,JStrin
)))))) 

【讨论】:

  • 我尝试在 Some(x) 的情况下打印 println(k.toString())、println(v.toString()),它给了我 JString(Bruce),但是当大小写匹配时完成后,我尝试打印我的对象 a,以检查 fstname 的值是否确实等于“Bruce”,但该对象仍有“John”。 (名称,JString(fstname)),(值,JString(John))))。似乎匹配发生了,但它没有保存到对象中。
  • 我已经添加了最终结果。它绝对有效。转换完成后尝试打印。
  • 我觉得自己像个白痴,因为正如你所说,它应该可以工作,而且看起来不错,但我似乎无法让它工作,这是我的代码的 pastebin跑步。我必须在这里遗漏一些基本的东西,也许 println 在案例匹配完成之前运行? pastebin.com/3XYW4Xgr
  • Pastebin - pastebin.com/up5ZTg0x。也许有更简单的方法可以做到这一点。
  • 我将您的最后一个 pastebin 与 json4s.jackson 中的合并功能结合起来,我设法让它工作。我不能感谢你的帮助,你是一个救生员。我在这里粘贴了我的最终代码。 pastebin.com/kChN7m1V
猜你喜欢
  • 2017-10-02
  • 2021-03-22
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多