Michael
Michael

Reputation: 42050

XML transformations in Scala

I am dealing with XML transformations right now. For example,

I am using standard scala.xml RewriteRule and RuleTransformer. I extend RewriteRule and pass it to a RuleTransformer instance, which applies the rule to XML.

I know there are other tools for that job: lenses, zippers, etc. Can they transform XMLs as I need? What are their advantages in comparison to my current approach?

Upvotes: 1

Views: 427

Answers (1)

Travis Brown
Travis Brown

Reputation: 139028

First for a side note: the Scala XML scene is pretty sad. Anti-XML was promising, but is now mostly abandoned (Arktekk got it working on 2.10, but I'm not sure how active that development is). Anti-XML did have a really neat zipper implementation, though, that would allow you to write stuff like this:

import com.codecommit.antixml._

val myDoc = <foo><a/><c x="xxx"/><a bar="baz"><b/></a></foo>.convert

def replaceA(e: Elem) = (e \\ "a").map(_.copy(name = "AAA")).unselect

def replaceXxxC(e: Elem) = (e \\ "c").filter(
  _.attrs.get("x").exists(_ == "xxx")
).map(_ => <d y="xxx"/>.convert).unselect

And then:

scala> println(replaceA(myDoc))
<foo><AAA/><c x="xxx"/><AAA bar="baz"><b/></AAA></foo>

scala> println(replaceXxxC(myDoc))
<foo><a/><d y="xxx"/><a bar="baz"><b/></a></foo>

The basic idea is that you use selectors like \\ to navigate into the XML, make "changes" locally with map, etc., and then back out of the zipper with unselect. This is the key benefit of using zippers (or lenses) for XML transformation—you get very imperative-like syntax for editing (it looks more or less just like navigation plus local changes) but also all the benefits of immutability.

Scales XML also lets you do this kind of thing, but it's quite a bit more complex.

Upvotes: 1

Related Questions