Tidhar Klein Orbach
Tidhar Klein Orbach

Reputation: 2966

How to create an array field in a json file using groovy GStringTemplateEngine

I want to create the following json:

{
"reviewers": [
    {
      "user": { 
        "name": "a"
      }
    },
    {
        "user": {
          "name": "b"
      }
    },
    {
        "user": {
          "name": "c"
      }
    }
  ]
}

using:

users= ["a", "b", "c"]
def binding = [
        arr : users
]

def f = new File(templateFileName)
def engine = new groovy.text.GStringTemplateEngine()
def template = engine.createTemplate(f).make(binding)
println template.toString()

I tried several variations for the template and ended with:

{
"reviewers": [
    <%  arr.each { out <<
  """ {
        "user": {
          "name": "${it}"
        }
},"""
} %>
]
}

this results in:

    {
  "reviewers": [
     {
        "user": {
          "name": "a"
        }
}, {
        "user": {
          "name": "b"
        }
}, {
        "user": {
          "name": "c"
        }
},// <-- illegal comma
]
}

the problem is with the last entry which adds a redundant comma (which cause the json to be illegal) is there a way do create it more elegantly so the last entry would not include the illegal comma?

Upvotes: 2

Views: 511

Answers (3)

Tidhar Klein Orbach
Tidhar Klein Orbach

Reputation: 2966

I have found another option for creating the template without using JsonBuilder.

In this case I used join(,) and therefore there was no redundant comma character at the end. (it also work as an inner part of a larger json file)

{"reviewers": [
    <%
     out << pullReqReviewers.collect { 
             "{ \"user\": { \"name\": \"${it}\"} } "
           }.join(',')
    %>
]}

Upvotes: 0

Rao
Rao

Reputation: 21379

You should be able to build it easily using JsonBuilder

def users= ["a", "b", "c"]
def jsonBuilder = new groovy.json.JsonBuilder() 
jsonBuilder { reviewers users.collect { u ->
    return { user { name (u) } }
  }
}
println(jsonBuilder.toPrettyString())​

Quickly can be tried the above example online Demo

Rao has the answer, but wrapping it as a template would look like:

def tpl = '''<%=
def jsonBuilder = new groovy.json.JsonBuilder() 
jsonBuilder {
    reviewers users.collect { u ->
        { -> user { name (u) } }
    }
}
jsonBuilder.toPrettyString()
%>'''

users= ["a", "b", "c"]
def binding = [
    users : users
]

def engine = new groovy.text.GStringTemplateEngine()
def template = engine.createTemplate(tpl).make(binding)
println template.toString()

Upvotes: 2

Andres Almiray
Andres Almiray

Reputation: 3281

An alternative would be to process each array element with a subtemplate (the second triple quoted text you pasted) using collect instead of each. Next, all elements are joined using ,\n, like this

tpl = '''{
"reviewers": [
    <%  out << arr.collect {
  """ {
    "user": {
      "name": "${it}"
    }
}"""
}.join(',\\n') %>
]
}
'''

users= ["a", "b", "c"]
def binding = [
    arr : users
]

def engine = new groovy.text.GStringTemplateEngine()
def template = engine.createTemplate(tpl).make(binding)
println template.toString()

Notice that out is given the result of the whole computation and not during each iteration.

Upvotes: 4

Related Questions