2

(これは、ここで尋ねられた質問に対するフォローアップの質問です)

Groovy の JsonBuilder を使用して、次の JSON を動的に生成しています。

{
    "type": {
        "__type": "urn",
        "value": "myCustomValue1"
    },
    "urn": {
        "__type": "urn",
        "value": "myCustomValue2"
    },
    "date": {
        "epoch": 1265662800000,
        "str": "2010-02-08T21:00:00Z"
    },
    "metadata": [{
        "ratings": [{
            "rating": "NR",
            "scheme": "eirin",
            "_type": {
                "__type": "urn",
                "value": "myCustomValue3"
            }
        }],
        "creators": [Jim, Bob, Joe]
    }]
}

このコードの使用:

def addUrn(parent, type, urnVal) {
    parent."$type" {
        __type "urn"
        "value" urnVal
    }
}

String getEpisode(String myCustomVal1, String myCustomVal2, String myCustomVal3) {    
    def builder = new groovy.json.JsonBuilder()
    builder {
        addUrn(delegate, "type", myCustomVal1)
        addUrn(delegate, "urn", "some:urn:$myCustomVal2")
        "date" {
            epoch 1265662800000
            str "2010-02-08T21:00:00Z"
        }
       "metadata" ({
                ratings ({
                        rating "G"
                        scheme "eirin"
                        addUrn(delegate, "_type", "$myCustomVal3")
                })
                creators "Jim", "Bob", "Joe"                    
        })
    }

    return root.toString();
}

コードは、 (ネストされた要素の下で)への3 回目の呼び出しのStackOverflowErrorためにスローします。その行をコメントアウトすると、完全に機能します (必要な情報のチャンクが欠落しているという事実を除いて)。addUrnratings

  1. なぜこうなった?
  2. デリゲートを直接の親に設定するにはどうすればよいratingsですか?

metaClass を使用してみましたが、役に立ちませんでした。

4

1 に答える 1

3

これはかなり醜い (LOL) ですが、期待どおりの結果が得られます。

def addUrn(parent, type, urnVal) {
    parent."$type" {
        __type "urn"
        "value" urnVal
    }
}

String getEpisode(String myCustomVal1, String myCustomVal2, String myCustomVal3) {
    def builder = new groovy.json.JsonBuilder()
    def root = builder {
        addUrn(delegate, "type", myCustomVal1)
        addUrn(delegate, "urn", "some:urn:$myCustomVal2")
        "date" {
            epoch 1265662800000
            str "2010-02-08T21:00:00Z"
        }
        "metadata" ([{([
                "ratings" ([{
                        rating "G"
                        scheme "eirin"
                        this.addUrn(delegate, "_type", "$myCustomVal3")
                }]),
                creators ("Jim", "Bob", "Joe")
        ])}])
    }

    println builder.toPrettyString()
}

ノート:-

  • 前の質問で、デリゲートが直系の親を参照する必要があると述べたのは誤りでした。実際には、直接の親を指します。addUrn代わりに、メソッドを呼び出すときに (メソッドを持つ) スクリプトを参照する必要がある ため、評価内でthis呼び出すときに を使用します。addUrnまたは、「評価」を のような方法で発送することもできますaddUrn
  • 括弧、チェーンブレース、角ブレースの使用と順序は、「メタデータ」の後に表示される重要なものです。ここでそれを理解するのは面倒です。ただし、注意すべきことは、メソッド呼び出しの使用、リストの宣言、およびクロージャーの使用の基本に固執することだけです。行ごとに各中かっこをインデントしてみてください。根底にある魔法をつかむことができます。:)
  • StackOverFlow エラーの理由は、スクリプトが所有するgetEpisodeメソッドにメソッドが到達できなかったことです。addUrn

Groovy Web コンソールで直接テストする

于 2013-06-28T03:40:28.083 に答える