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.