Bummer you can't write what you wanted. I guess the Scala compiler's XML literal parser isn't sophisticated enough to parse XML literals with expressions just inserted anywhere. They can only be between tags or as individual attribute values.
As a workaround, it is possible to create the element with no attributes, or just the one attribute and the rest missing:
val elem = <input type="text"/>
Then you can add the attributes from your Map
with a couple of copy constructors.
elem.copy(
attributes = elem.attributes.copy(
config.foldLeft(scala.xml.Null: scala.xml.MetaData) {
case (next, (k, v)) => scala.xml.Attribute(k, scala.xml.Text(v), next)
}
))
res1: scala.xml.Elem = <input type="text" k2="v2" k1="v2"/>
The above uses the copy constructor for the Elem
and then one for the attributes
.
There's also the option of just using one copy constructor and folding a little differently:
elem.copy(attributes = config.foldRight(elem.attributes) {
case ((k, v), next) => scala.xml.Attribute(k, scala.xml.Text(v), next)
})
res2: scala.xml.Elem = <input k1="v2" k2="v2" type="text"/>
That might be the simplest option.
Although, Olivier's solution does show that UnprefixedAttributed
will accept a String
for an attribute value.
elem.copy(attributes = config.foldRight(elem.attributes) {
case ((k, v), next) => new scala.xml.UnprefixedAttribute(k, v, next)
})
res3: scala.xml.Elem = <input k1="v2" k2="v2" type="text"/>
That avoids having to make a Text
element so that you provide a NodeSeq
value for Attribute
.