0

私は適切な Scala JSON ライブラリを選択しようとしていますが、lift-json現時点ではそれが最良の選択であるというコンセンサスが得られているようです。

呪文のためにそれ (バージョン 2.5.1) を試した後、私が必要としていたことのほとんどをかなり簡単に行うことができましたJValue

の次のインスタンスがあるとしますJValue

val john = ("id"   -> 1) ~
           ("name" -> "Foo") ~
           ("nested" ->
             ("id" -> 2) ~
             ("name" -> "Bar"))

Foo親要素の名前を からに変更したいのですがfoo。私はtransform方法が行く方法だと思った:

john transform {
    case JField("name", _) => JField("name", "foo")
})

しかし、これにより、親要素とネストされた要素の両方のnameフィールドが変更されfooます。振り返ってみると、これは驚くべきことではありませんでした。

ドキュメントとコードを確認しましたが、 のキーを持つ特定のフィールドを選択する方法が見つかりませんでしたname。私は何か見落としてますか?

もう1つの解決策(そしてこれが機能する)は、2つのJValueオブジェクトをマージしているようですが、少し冗長に見えます:

john merge JObject(JField("name", "foo") :: Nil)

同じ結果を達成する組み込みの読みやすい方法はありますか? JFieldからへの暗黙的な変換を書くこともできるかもしれませんが、そのようなメカニズムがまだないのはJObject奇妙に思えます。lift-jsonもし私が賭けなければならないとしたら、それはそれが存在しないというよりも、私がそれを見つけられなかったことにあるでしょう。

編集:私は今少しばかげていると感じます

john transform {
    case JField("name", "Foo") => JField("name", "foo")
})

世界で最も最適なソリューションではありませんが、完全に読みやすく簡潔です。

4

2 に答える 2

0

これは変更可能な変数を使用し、json4s (ボンネットの下で lift-json を使用する) も使用するため醜いですが、機能します:

import org.json4s.JsonAST._
import org.json4s.native.JsonMethods._
import org.json4s.JsonDSL._

object JsonTesting {
  def main(args: Array[String]) {
    val john = ("id"   -> 1) ~
           ("name" -> "Foo") ~
           ("nested" ->
             ("id" -> 2) ~
             ("name" -> "Bar"))

    var changed = false
    val john2 = john transformField {
      case JField("name", _) if !changed => 
        changed = true
        JField("name", "foo")
    }
  }
}

深さの 1 レベルのみをトラバースするか、チェックされた各ノードの深さを認識するように指示するよりクリーンな方法を見つけることができなかったので、深さの最初のレベルでのみ切り替えを行います。

于 2013-07-18T19:09:35.370 に答える
0

replace次のように JValueのメソッドを使用します。

john.replace(List("name"), "foo")

この「replace」メソッドの実装は惨事であり、replace という名前は (私には) 真実ではない状態の変更を示唆していますが、実際には機能します。

JObject(List((id,JInt(1)), (name,JString(foo)), (nested,JObject(List((id,JInt(2)), (name,JString(Bar)))))))

于 2014-04-13T20:20:03.860 に答える