Your original code seems to be correct. The problem is not that it does not work recursively (it does), but a weird issue that occurs when there is exactly one existing attribute.
Look at the following, which is basically identical to your code except I've added some print statements for debugging:
val rule = new RewriteRule() {
override def transform(node: Node): Seq[Node] = {
println("transforming '" + node + "'")
val result = node match {
case elem @ Elem(prefix, label @ "bar", attribs, scope, children @ _*) =>
Elem(prefix, label, attribs append Attribute(None, "newKey", Text("newValue"), Null), scope, children: _*)
case other => other
}
println("result: '" + result + "'")
result
}
}
object xf extends RuleTransformer(rule)
Now we test it:
scala> xf { <bar/> }
transforming '<bar></bar>'
result: '<bar newKey="newValue"></bar>'
transforming '<bar></bar>'
result: '<bar newKey="newValue"></bar>'
res0: scala.xml.Node = <bar newKey="newValue"></bar>
We see that for an element without attributes, the transformation results in the new attribute being added, and the returned result is correct as well. (I don't know why the transformation occurs twice.)
However, when there is an existing attribute:
scala> xf { <bar key1="value1"/> }
transforming '<bar key1="value1"></bar>'
result: '<bar key1="value1" newKey="newValue"></bar>'
res1: scala.xml.Node = <bar key1="value1"></bar>
The result of the transformation is correct, but it is not propagated to the final result!
But when there are two (or more) existing attributes, everything is fine:
scala> xf { <bar key1="value1" key2="value2"/> }
transforming '<bar key1="value1" key2="value2"></bar>'
result: '<bar key2="value2" key1="value1" newKey="newValue"></bar>'
transforming '<bar key1="value1" key2="value2"></bar>'
result: '<bar key2="value2" key1="value1" newKey="newValue"></bar>'
res2: scala.xml.Node = <bar key2="value2" key1="value1" newKey="newValue"></bar>
I'm tempted to believe this is a bug in the library.