2

私はこの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": ""
                }
            ]
        }
    ]
}

「フィールド」と呼ばれる 2 番目の配列は、空の文字列を実際の文字列値に置き換えたい配列です。最初にjsonをJObjectに解析し、次にJObjectを新しい値で変換することにより、json4s transformField関数でこれを行ってきました。

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" を取得し、"v" のフィールドが更新された新しい JArray を取得しました。最後に、新しい値を元の JObject "a" にマージする必要があります。これを置換で試しましたが、運がありませんでした。

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

質問:

  1. 2 回目に出現したフィールド配列を置き換えるために replace() を取得するにはどうすればよいですか?
  2. これを行うより良い方法はありますか?提案は非常に高く評価されています。

これは、コードの実行可能なバージョン全体で、json の印刷例も含まれています: http://pastebin.com/e0xmxqFF

4

1 に答える 1

6

更新したいフィールドについて非常に具体的であるため、最も簡単な解決策は次を使用することだと思いますmapField

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

replacereplace最初の引数がフィールド名のリストであると予想されるため、インデックスを渡す必要があるため、これは機能しません。

于 2015-01-15T17:08:57.650 に答える