I am trying to replace XML fragments and you need a battery along the way. Let's say I have a populated question that is stored as XML:
val q = <text>The capitals of Bolivia are <blank/> and <blank/>.</text>
At some point, I want to turn these spaces into HTML input elements, and I need to be able to distinguish between the first and second so that I can check them. (Ignore the fact that in this case, the two capitals can appear in any order - with a headache, which I will deal with later).
Thanks to the excellent answers on StackOverflow, I created the following solution:
import scala.xml._ import scala.xml.transform._ class BlankReplacer extends BasicTransformer { var i = 0 override def transform(n: Node): NodeSeq = n match { case <blank/> => { i += 1 <input name={ "blank.%d".format(i) }/> } case elem: Elem => elem.copy(child=elem.child.flatMap(transform _)) case _ => n } }
and it works quite well. I need to create new BlankReplacer() every time I want to start re-numbering, but this works a lot:
scala> new BlankReplacer()(q) res6: scala.xml.Node = <text>The capitals of Bolivia are <input name="blank.1"></input> and <input name="blank.2"></input>.</text>
That is the question. Is there an easy way to avoid the mutation that I have to do every time I replace <blank/> ? What I have does not seem terrible to me, but I think it could be cleaner if I did not create a new instance of the BlankReplacer class every time I had to convert the question to HTML. I'm sure there is a way to turn this into a drive, but I'm not sure how to do this.
Thanks! Todd
source share