Prompted by someone wondering whether Scala could replace XSLT (I happen to think XSLT is very hard to beat when you deal with XML documents as opposed to whatever else it's (mis)used for), I started a little experiment: a demonstration of the <xsl:apply-templates/> and <xsl:template match="foo"/> combo in Scala. See
Example1.scala (the whole project is just 2 files).
The idea is that the user of this tool writes templates, each of which is supposed to match one node and do something useful on a successful match. Return values are gathered into a result tree. The special applyTemplates(group) call recursively applies the machinery to the specified group.
Because we're using a language with native matching capabilities, I decided to try how far a PartialFunction would take me, instead of a full-blown language like xpath.
case Elem(None, "title", _, _, cs) =>
Elem(None, "h1", Attributes(), Map(), applyTemplates(cs))
then I observe the following (concentrating on the matching):
a) Yay! it works
b) It's ugly and long-winded, with too many underscores and commas
c) It can't match on parents ("chapter/title" in xpath), but attributes and children can be queried, although that too takes many characters to write out
Solutions I can think of:
b) custom extractors: e@E("title") => applyTemplates(e \ *)
c) something to do with Zippers?
Aside: I'm currently not using zippers, but I already noticed something strange would happen if I were to use them to navigate the tree: Normally you'd use this tool to create an output tree from scratch, but because I use flatMap on the current selection, I will get a giant confused zipper that I really didn't ask for. I know I can strip the zipper, but it seems wasteful to even create one.
Can I have a zipperless flatMap?
Now continuing with c, using a zipper I at least have access to the zipper's parent. But when I flatMap a zipper, I get a plain Node passed to my function, so I'll need to pass something extra (the zipper being traversed I guess) if I want to give my templates access to the parent. Right now it looks like the match expressions will become pretty convoluted, but I'll have a look at what the custom extractors can do.
Observations on generating XML will follow in another mail.
Regards,
Bart.