1
0
-1

I've encountered a JSON structure like the following:

{
    "params": {
        "firstName": {
            "label": "First Name",
            "type": "String"
        },
        "surname": {
            "label": "Last Name",
            "type": "String"
        }
    }
}

Note that the params element contains a list of similar sub elements but it is not represented as an array as you would expect. The names of those sub elements cannot be predicted so we can't query them explicitly.

I want to iterate through the sub elements using the Path class in a manner that allows me to access the name of the element (e.g. "firstName", "surname") but don't see an obvious way to do that. The following code shows what I'd like to achieve but doesn't compile as there is no attribute called name on the Path object.

Path jsonPath = new Path(JSON_DATA)
jsonPath.paths("params.*").each{
    println it.name + " - [" + it.val("type") + "] " + it.val("label")
}

The result should be output as follows:

firstName - [String] First Name
surname - [String] Last Name

Anyone got advice on how to achieve this?

    CommentAdd your comment...

    2 answers

    1.  
      2
      1
      0

      Found the answer thanks to Radoslav Ivanov

          Path jsonPath = new Path(JSON_DATA)
          ((Map) jsonPath.val("params")).each {
              println it.key + " - [" + jsonPath.val("params.${it.key}.type") + "] " + jsonPath.val("params.${it.key}.label")
          }
        CommentAdd your comment...
      1.  
        2
        1
        0

        Hi Ben,

        Wouldn't just plain 'ol Groovy be neater?

        String JSON_DATA = """{
            "params": {
                "firstName": {
                    "label": "First Name",
                    "type": "String"
                },
                "surname": {
                    "label": "Last Name",
                    "type": "String"
                }
            }
        }
        """
        def jsonData = new groovy.json.JsonSlurper().parseText(JSON_DATA)
        println jsonData.params.subMap(jsonData.params.keySet())

        Gives you this output:

        [firstName:[label:First Name, type:String], surname:[label:Last Name, type:String]]

        And you only need to manage the name of the outer map.

        credit: http://mrhaki.blogspot.co.uk/2009/10/groovy-goodness-getting-submap-from-map.html
        1. Ben Warner

          Actually the reason I was looking at the Path class is because I was looking for an alternative to JsonSlurper as it re-orders the parameters alphabetically according to their key which was entirely undesirable for my application. Not sure why it does this and there doesn't seem to be a way to turn it off.

          In the example JSON_DATA above if you put type above label you will still get the same output with type appearing after label in the output.

        CommentAdd your comment...