5

コードランドで大きな問題が発生したため、助けが必要です!

Groovy と JsonSlurper を使用して、以下の形式の JSON を処理しています。「タイプ」キーが特定の値に設定されている場合、外側の要素 (私の場合、これはすべてマップである必要があります) を探しています。たとえば、タイプが「Type5」の場合、3 つのマップを取得する必要があります。外側の Type5 を含む「ボディ」マップ、内側の Type5 を含む「ボディ」マップ、および下部近くの Type5 マップ (それぞれの EntrySet も問題なく機能します)。Type3 と Type4 は同じ動作を示します。

有効な Json を持つようにリクエストごとに編集

これをGroovyのJsonSlurperで実行したので、有効なはずです。

{
"type": "Run1",
"body": [
{
  "type": "Type1",
  "expression": {
    "type": "Type2",
    "expressions": [
      {
        "type": "Type3",
        "body": {
          "type": "Type4",
          "id": null,
          "params": [
            {
              "type": "Identifier",
              "name": "a"
            },
            {
              "type": "Identifier",
              "name": "b"
            },
            {
              "type": "Identifier",
              "name": "c"
            }
          ],
          "body": {
            "type": "Type5",
            "body": [
              {
                "type": "Type6",
                "id": {
                  "type": "Identifier",
                  "name": "d"
                },
                "params": [
                  {
                    "type": "Identifier",
                    "name": "a"
                  }
                ],
                "body": {
                  "type": "Type5",
                  "body": [
                    {
                      "type": "Type7",
                      "contents": {
                        "type": "Type8",
                        "leftcontents": {
                          "type": "Literal",
                          "value": "specific name",
                        },
                        "rightcontents": {
                          "type": "Type3",
                          "body": {
                            "type": "Type4",
                            "object": {
                              "type": "Identifier",
                              "name": "o"
                            },
                            "property": {
                              "type": "Identifier",
                              "name": "f"
                            }
                          },
                          "contents": [
                            {
                              "type": "Identifier",
                              "name": "a"
                            }
                          ]
                        }
                      }
                    }
                  ]
                },
              },
              {
                "type": "Type6",
                "id": {
                  "type": "Identifier",
                  "name": "e"
                },
                "params": [
                  {
                    "type": "Identifier",
                    "name": "a"
                  }
                ],
                "defaults": [],
                "body": {
                  "type": "Type5",
                  "body": [
                    {
                      "type": "Type7",
                      "contents": {
                        "type": "Type8",
                        "leftcontents": {
                          "type": "Literal",
                          "value": "string",
                        },
                        "rightcontents": {
                          "type": "Type9",
                          "argument": {
                            "type": "Identifier",
                            "name": "a"
                          },
                          "prefix": true
                        }
                      }
                    }
                  ]
                },
              }
            ]
          }
        }
      }
    ]
  }
}
]
}

私はちょうどこれをやっています:

FileInputStream fis = new FileInputStream('myInput.json')
def jsonData = (new JsonSlurper()).parse(fis)

構造の個々の部分に簡単にアクセスできますが、任意のネスト レベルを持つすべての「Type5」を取得することは、私には不可能です。誰かがこれにいくつかの輝きを放つことができますか?

4

1 に答える 1

11

基本的に、すべてのマップを収集し、コレクションとすべてのマップ値に対して再帰します。例えば:

def json='{"type":"Run1","body":[{"type":"Type1","expression":{"type":"Type2","expressions":[{"type":"Type3","body":{"type":"Type4","id":null,"params":[{"type":"Identifier","name":"a"},{"type":"Identifier","name":"b"},{"type":"Identifier","name":"c"}],"body":{"type":"Type5","body":[{"type":"Type6","id":{"type":"Identifier","name":"d"},"params":[{"type":"Identifier","name":"a"}],"body":{"type":"Type5","body":[{"type":"Type7","contents":{"type":"Type8","leftcontents":{"type":"Literal","value":"specificname",},"rightcontents":{"type":"Type3","body":{"type":"Type4","object":{"type":"Identifier","name":"o"},"property":{"type":"Identifier","name":"f"}},"contents":[{"type":"Identifier","name":"a"}]}}}]},},{"type":"Type6","id":{"type":"Identifier","name":"e"},"params":[{"type":"Identifier","name":"a"}],"defaults":[],"body":{"type":"Type5","body":[{"type":"Type7","contents":{"type":"Type8","leftcontents":{"type":"Literal","value":"string",},"rightcontents":{"type":"Type9","argument":{"type":"Identifier","name":"a"},"prefix":true}}}]},}]}}}]}}]}'
def slrp = new groovy.json.JsonSlurper().parseText(json)

def collectMaps(e) {
    e.with{
        if (it instanceof Map) {
            [it] + it.values().collect{ collectMaps(it) }
        } else if (it instanceof Collection) {
            it.collect{ collectMaps(it) }
        } else {
            []
        }
    }.flatten()
}

assert collectMaps(slrp).findAll{ it.type=='Type5' }.size()==3
assert collectMaps(slrp).findAll{ it.type=='Type3' }.size()==2
于 2015-01-22T22:49:52.080 に答える