0

I've this code by which I am trying to set the value of a Key (a json node id). But its not setting the value. Log.info statement is showing right values.

Key= context.expand( '${#Project#key}' )
Value= context.expand( '${#Project#value}' )
Binding binding = new Binding()
binding.setVariable("v", "$Value")
binding.setVariable("k", "$Key")
log.info(binding.getVariable("v"))  // gives me the value 1234
log.info(binding.getVariable("k"))  // gives me the value request.id
def SetKey = new GroovyShell(binding).evaluate( "k=v")

Can someone please comment on whats wrong in this code. and how can I correct it.

Edit: Explanation of the issue

In SoapUI I've some json nodes saved in data source like this request.id and request.app.id and there expected values in Value column which I am fetching through Key and Value above. I am hoping to change the value of a json node to its respective value at run time. So for each iteration of data source, it should set the correct value of that particular json node. Befor the above code I've parsed my json request by json slurper and after the above code I am building the json again by Json builder and running the request. Parsing and running the request works fine, its just that I couldnt set the value of the json node.

user1207289
  • 3,060
  • 6
  • 30
  • 66
  • Please describe your problem, instead of just the broken solution. – SiKing Sep 23 '14 at 15:57
  • @SiKing , Thank you for your response. Sorry if i was short on explanation. I've edited the original question. – user1207289 Sep 23 '14 at 16:15
  • I just asked this the other day: http://stackoverflow.com/a/25901091/3124333 – SiKing Sep 23 '14 at 18:23
  • @SiKing That is what I am trying. I have tried `def SetKey = new GroovyShell(binding).evaluate( "k=v")` , `evaluate( 'k="v"')` and `evaluate( 'k="$v"')`. But it doesnt show me the changed value in request.In the first case, when I do `log.info(SetKey)` , it shows me the correct value but not when I print out the whole request in script log. Is there anything I am forgetting to return to main script where I am building the request again? – user1207289 Sep 23 '14 at 20:19
  • @SiKing I guess this could be my problem but I dont know how to overcome this. If the assignment is happening in GroovyShell context, how would I make that assignment affect the request which is building in the context of main script. Any idea will be greatly appreciated. Thanks! – user1207289 Sep 24 '14 at 15:39
  • I still do not understand why you think `GroovyShell` is automagically going to change your JSON node. To modify JSON, try this: http://siking.wordpress.com/2013/07/05/dynamically-create-elements-in-a-soapui-request-json-version/ To correctly evaluate an expression using `GroovyShell` see the link in my previous comment. – SiKing Sep 24 '14 at 18:09
  • @SiKing Thank You for your response Not automatically , before `Groovyshell` step , I am doing this step `request = slurper.parseText(RawRequest)` and then I want to execute `Key=Value` where `Key` has a value of `request.id` and `Value` has a value of `1234`. When I execute without variables like this `request.id=1234` the node changes, I could see it in the newly built Json. I am struggling to the same with the use of variables because I am getting these `Key` and `Value` values from datasource. I'll look into the link you provided. – user1207289 Sep 24 '14 at 20:06
  • @SiKing I looked at the link you provided, it is only creating a map of first level nodes of json. And the deeper nodes are harcoded `result.markets[0].selections[0]`. Is there a way to convert all of json to groovy map recursively .My Search shows that there is way in `grails` . Would you happen to know any other way I can tackle this issue or maybe how to convert all json to map in groovy. – user1207289 Sep 25 '14 at 15:23
  • `JsonSlurper()` processes JSON same as this: http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper – SiKing Sep 25 '14 at 15:46
  • @SiKing solved the issue that I explained above but not through bind variables, just thought of posting the solution. [here](http://stackoverflow.com/questions/26060955/executing-code-dynamically-in-groovy/26074730#26074730). it is . Thanks. – user1207289 Sep 30 '14 at 17:32

1 Answers1

0

If your keys are just dotted names, you could simply use some string manipulation, no need to involve the Groovy parser.

For example, if they all begin with request:

def steps = Key.split(/\./)
if (steps.size() < 2 || steps[0] != 'request') {
    throw ...
}
def obj = request
if (steps.size() > 2) {
    steps[1..-2].each { 
        obj = obj[it] 
    }
}
obj[steps[-1]] = Value
Tobia
  • 17,856
  • 6
  • 74
  • 93
  • I havent tried it but the way it is now is I am avoiding spliting the `Key` and using it directly from datasource like this `def slurper = new JsonSlurper()` `def parsed_MessageBody = slurper.parseText(RawRequest)` `def node= "parsed_MessageBody"+"."+Key` `Eval.me('parsed_MessageBody', parsed_MessageBody, "$node = '$Value'")`. seems to be working fine. I parsed it so we can assign new value to Json object. I am not understanding where in your code your are doing that. But it may it be my limited groovy knowledge. But thank you for your input. – user1207289 Oct 02 '14 at 19:11