{foo("text nod" /> {foo("text nod" /> {foo("text nod"/>

Function calls for dynamic XML in Scala

156 views Asked by At

Let's say I have the following code:

import scala.xml._

def foo(bar:String) = s"The FOO is $bar"

var xml =
    <a type ={foo("attribute")}>
        {foo("text node")}
    </a>

val txt = "<a>{foo(\"updated\")}</a>"

XML.loadString(txt)

That results in

xml: scala.xml.Elem = <a>{foo(&quot;updated&quot;)}</a>

What is the canonical way to make it

xml: scala.xml.Elem = <a>The FOO is updated</a>

Is it even possible without reflection?

2

There are 2 answers

0
vnfedotov On BEST ANSWER

I guess it's my own fault of trying to make the question as general as possible. The answer I was looking for was some way of updating XML literals from external storage in runtime.

Best way to do that are template engines. There are several options for Scala:

  • Twirl
  • Scalatags
  • Scalate

For the purpose of my project I've found Scalate to be the best fit. So, answering my own question, it would look something like this:

import scala.xml._
import org.fusesource.scalate._

def foo(bar:String) = s"The FOO is $bar"

val engine = new TemplateEngine
val template = engine.load("test.ssp", List(Binding("foo", "String")))
val str1 = engine.layout("test.ssp",Map("foo"-> foo("bar")))
val str2 = engine.layout("test.ssp",Map("foo"-> foo("updated")))

with template "test.ssp" being simply:

<a>${foo}</a>
1
Chaitanya On

You can try

val txt1 = s"<a>${foo("updated")}</a>"
XML.loadString(txt1)

This represent the xml in format as

res0: scala.xml.Elem = <a>The FOO is updated</a>