avidCoder
avidCoder

Reputation: 490

How to add json field to required json and at particular place using groovy?

I have the following json:

def desiredJson = '{"count": 4, "max": "12", "min": 0, "details": [{"goBus": {"first": 12800, "second": 11900, "third": 12800},"goAir": {"first": 12800, "second": 11900, "third": 12800}, "gotTrain": {"first": 12800, "second": 11900},"sell": true, "darn": 2,"rate": [{ "busRate": 11900, "flag": false, "percent": 0}],}],}'

I want to add "total": "1000" key-value pair after "sell": true.

So far I have tried following:

def json = new JsonSlurper().parseText(desiredJson)
json.put('total', '1000')
log.info JsonOutput.toJson(json)

But it appends this pair at any place. Like this:

{
"count": 4,
"details": [{
    "darn": 2,
    "goAir": {
        "first": 12800,
        "second": 11900,
        "third": 12800
    },
    "goBus": {
        "first": 12800,
        "second": 11900,
        "third": 12800
    },
    "gotTrain": {
        "first": 12800,
        "second": 11900
    },
    "rate": [{
        "busRate": 11900,
        "flag": false,
        "percent": 0
    }],
    "sell": true
}],
"max": "12",
"min": 0,
"total": "1000"
}

Can we add it at any particular position? I have gone through this question which was already asked - Add JSON object to Another JSON Object at particular place . But I couldn't get any clue from this.

Also if this desiredJson has repetitive object like this:

{
"count": 4,
"details": [{
    "darn": 2,
    "goAir": {
        "first": 12800,
        "second": 11900,
        "third": 12800
    },
    "goBus": {
        "first": 12800,
        "second": 11900,
        "third": 12800
    },
    "gotTrain": {
        "first": 12800,
        "second": 11900
    },
    "rate": [{
        "busRate": 11900,
        "flag": false,
        "percent": 0
    }],
    "sell": true
}],
"max": "12",
"min": 0,
"total": "1000"
},
{
"count": 5,
"details": [{
    "darn": 3,
    "goAir": {
        "first": 800,
        "second": 1100,
        "third": 1200
    },
    "goBus": {
        "first": 1200,
        "second": 100,
        "third": 1280
    },
    "gotTrain": {
        "first": 100,
        "second": 1900
    },
    "rate": [{
        "busRate": 1190,
        "flag": false,
        "percent": 1
    }],
    "sell": true
}],
"max": "14",
"min": 0,
"total": "1001"
},
{
"count": 6,
"details": [{
    "darn": 5,
    "goAir": {
        "first": 1800,
        "second": 1100,
        "third": 1280
    },
    "goBus": {
        "first": 1280,
        "second": 1190,
        "third": 1280
    },
    "gotTrain": {
        "first": 1280,
        "second": 1100
    },
    "rate": [{
        "busRate": 900,
        "flag": false,
        "percent": 7
    }],
    "sell": true
}],
"max": "19",
"min": 0,
"total": "1002"
}

total key's value should be added and incremented both.

Upvotes: 1

Views: 2505

Answers (2)

Szymon Stepniak
Szymon Stepniak

Reputation: 42194

First thing - if you want to repeat JSON object in the document, you have to put it into array. In your case valid JSON document would look like this:

[
  {
    "count": 4,
    "details": [
      {
        "darn": 2,
        "goAir": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "goBus": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "gotTrain": {
          "first": 12800,
          "second": 11900
        },
        "rate": [
          {
            "busRate": 11900,
            "flag": false,
            "percent": 0
          }
        ],
        "sell": true
      }
    ],
    "max": "12",
    "min": 0
  },
  {
    "count": 4,
    "details": [
      {
        "darn": 2,
        "goAir": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "goBus": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "gotTrain": {
          "first": 12800,
          "second": 11900
        },
        "rate": [
          {
            "busRate": 11900,
            "flag": false,
            "percent": 0
          }
        ],
        "sell": true
      }
    ],
    "max": "12",
    "min": 0
  },
  {
    "count": 4,
    "details": [
      {
        "darn": 2,
        "goAir": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "goBus": {
          "first": 12800,
          "second": 11900,
          "third": 12800
        },
        "gotTrain": {
          "first": 12800,
          "second": 11900
        },
        "rate": [
          {
            "busRate": 11900,
            "flag": false,
            "percent": 0
          }
        ],
        "sell": true
      }
    ],
    "max": "12",
    "min": 0
  }
]

Now, if you want to add total field the each object in the array in path $.details.total then you can do something like that:

def json = new JsonSlurper().parseText(desiredJson)

int total = 1000
json.details.each { it.get(0).put('total', total++) }

println JsonOutput.prettyPrint(JsonOutput.toJson(json))

If you want to add total field to path $.details.rate.total then you do:

json.details.rate.each { it.flatten().get(0).put('total', total++) }

instead.

Output

[
    {
        "count": 4,
        "details": [
            {
                "darn": 2,
                "goAir": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "goBus": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "gotTrain": {
                    "first": 12800,
                    "second": 11900
                },
                "rate": [
                    {
                        "busRate": 11900,
                        "flag": false,
                        "percent": 0
                    }
                ],
                "sell": true,
                "total": 1000
            }
        ],
        "max": "12",
        "min": 0
    },
    {
        "count": 4,
        "details": [
            {
                "darn": 2,
                "goAir": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "goBus": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "gotTrain": {
                    "first": 12800,
                    "second": 11900
                },
                "rate": [
                    {
                        "busRate": 11900,
                        "flag": false,
                        "percent": 0
                    }
                ],
                "sell": true,
                "total": 1001
            }
        ],
        "max": "12",
        "min": 0
    },
    {
        "count": 4,
        "details": [
            {
                "darn": 2,
                "goAir": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "goBus": {
                    "first": 12800,
                    "second": 11900,
                    "third": 12800
                },
                "gotTrain": {
                    "first": 12800,
                    "second": 11900
                },
                "rate": [
                    {
                        "busRate": 11900,
                        "flag": false,
                        "percent": 0
                    }
                ],
                "sell": true,
                "total": 1002
            }
        ],
        "max": "12",
        "min": 0
    }
]

Keep in mind, that it adds total right after sell key, but from the JSON document validation perspective, it doesn't matter if this is before or after sell field. It shouldn't even matter when this document gets parsed by a consumer.

Upvotes: 1

cfrick
cfrick

Reputation: 37033

No you can't (well sure you can, but why bother). Here is why:

Object: an unordered collection of name–value pairs

Source

So if something upstream needs to have this in order, then it's broken.

Upvotes: 2

Related Questions