3

If I have code such as (which doesn’t work):

def value = element.getAttribute("value")
Binding binding = new Binding();
binding.setVariable("valueExpression", value);
def interpolatedValue = new GroovyShell(binding).evaluate("return valueExpression")
println ("interpolated Value = $interpolatedValue")

and the value from the xml attribute is “The time is ${new Date()}”

how do I get Groovy to evaluate this expression at runtime?

Using the above code I get “The time is ${(new Date()}” instead of an evaluation….

Thanks for any thoughts….

phil swenson
  • 8,564
  • 20
  • 74
  • 99

2 Answers2

1

Hmm. Firstly I have tried, as Michael, using inline xml. But It's seems, that groovy can properly treat them as GString.

So, I have managed make things to work using another way: Templates

def xml = new XmlSlurper().parse("test.xml")
def engine = new groovy.text.SimpleTemplateEngine()
def value = xml.em."@value".each { // iterate over attributes
    println(engine.createTemplate(it.text()).make().toString())
}

test.xml

<root>
    <em value="5"></em>
    <em value='"5"'></em>
    <em value='${new Date()}'></em>
    <em value='${ 5 + 4 }'></em>
</root>

output

5
"5"
Wed Feb 26 23:01:02 MSK 2014
9

For pure Groovy shell solution, I think we can wrap expression in additional ", but I haven't get any solution yet.

Seagull
  • 13,484
  • 2
  • 33
  • 45
  • I'm working with an existing xml based test scripting framework, so I need to work with in the confines of capturing an expression from an XML attribute... if I were starting over I would use templating. Actually I wouldn't even use XML :) – phil swenson Feb 26 '14 at 16:08
  • I may be wrong in understanding what you want to achieve. I have provided xml element based example for simplicity, but now I have edited an answer to show you full working example. Note, that this solution, in opposite to __newbies__ one keep's `"` in attribute text correctly. It's smarter, than simply add `"` at each attribute. In other cases, nothing differ, you can get your string from any source using any api, then pass it to template and get expected result as a String. If you meant smth other, please clarify. – Seagull Feb 26 '14 at 19:10
  • I ended up using the templating as well, my code is similar. – phil swenson Feb 26 '14 at 20:34
0

You can also use the following code:

def value = element.getAttribute("value")
Binding binding = new Binding()
binding.setVariable("valueExpression", "\"$value\"")
binding.setVariable("a", 10)
binding.setVariable("b", 20)
def interpolatedValue = new GroovyShell(binding).evaluate(
    "return evaluate(valueExpression)")
println ("interpolated Value = $interpolatedValue")

I'm testing the code above using the following element:

The time is ${new Date()} and $a + $b is ${a+b}

The result is:

interpolated value = The time is Wed Feb 26 10:00:00 2014 and 10 + 20 is 30
jocki
  • 1,728
  • 16
  • 26
  • using your code, binding.setVariable("valueExpression", "\"value\"") just sets valueExpression to the literal "value", not the expression contained in "value" Are you sure you pasted it in the way you intended? – phil swenson Feb 26 '14 at 16:06
  • Sorry, I'm missing the dollar character. What I'm doing is wrapping the original value in quotes to make it a GString again and re-evaluating it in the binding. – jocki Feb 26 '14 at 16:21