【问题标题】:replace object in Json AST with json4s.replace用 json4s.replace 替换 Json AST 中的对象
【发布时间】:2015-01-15 13:53:21
【问题描述】:

我有这个json,我一直在用json4s解析和替换字段,json看起来像这样:

{
    "id": "6988",
    "signatories": [
        {
            "fields": [
                {
                    "name": "fstname",
                    "value": "Bruce"
                },
                {
                    "name": "sndname",
                    "value": "Lee"
                },
                {
                    "name": "email",
                    "value": "bruce.lee@company.com"
                },
                {
                    "name": "sigco",
                    "value": "Company"
                },
                {
                    "name": "mobile",
                    "value": "0760000000"
                }
            ]
        },
        {
            "fields": [
                {
                    "name": "fstname",
                    "value": ""
                },
                {
                    "name": "sndname",
                    "value": ""
                },
                {
                    "name": "email",
                    "value": ""
                },
                {
                    "name": "mobile",
                    "value": ""
                },
                {
                    "name": "sigco",
                    "value": ""
                }
            ]
        }
    ]
}

第二个数组叫做“fields”,我想用实际的字符串值替换空字符串。我一直在使用json4s transformField 函数执行此操作,首先将 json 解析为 JObject,然后使用新值转换 JObject。

val a = parse(json)

// transform the second occurance of fields (fields[1])
val v = a.\("signatories").\("fields")(1).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("New name")) }
      }
    }

现在我得到了原始解析的 json“a”,并且得到了新的 JArray,其中包含“v”中的更新字段。我需要做的最后一件事是将新值合并到原始 JObject“a”中。我用替换试过这个,没有运气。

val merged = a.replace(List("fields"), v)

问题:

  1. 如何让 replace() 替换第二次出现的字段数组?
  2. 有没有更好的方法来做到这一点?非常感谢您的建议。

这里是完整的代码的可运行版本,以及 json 的示例打印: http://pastebin.com/e0xmxqFF

【问题讨论】:

    标签: json scala json4s


    【解决方案1】:

    由于您对要更新的字段非常具体,我认为最直接的解决方案是使用mapField

     val merged = a mapField {
        case ("signatories", JArray(arr)) => ("signatories", JArray(arr.updated(1, JObject(JField("fields", v)))))
        case other => other
      }
    

    replace 据我所知,不能使用,因为您需要向它传递一个索引,这是行不通的,因为replace 期望它的第一个参数是字段名称列表。

    【讨论】:

    • 这是天才,先生,是个巫师。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    相关资源
    最近更新 更多